diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..c861cca
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at joel.costigliola@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/README.md b/README.md
index d18a6fa..4000ff3 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
The Assertions Generator can create specific assertions for your classes. It comes with :
* a CLI tool (this project)
-* a [**maven plugin**](https://github.com/assertj/assertj-assertions-generator-maven-plugin).
+* a [**maven plugin**](https://github.com/assertj/assertj-generator/tree/main/assertj-generator-maven-plugin).
* a [**gradle plugin**](https://github.com/assertj/assertj-generator-gradle-plugin).
Let's say you have a `Player` class with `name` and `team` properties. The generator will create a `PlayerAssert` assertions class with `hasName` and `hasTeam` assertions. This allows you to write :
diff --git a/assertj-generator-maven-plugin/README.md b/assertj-generator-maven-plugin/README.md
new file mode 100644
index 0000000..b2a2de7
--- /dev/null
+++ b/assertj-generator-maven-plugin/README.md
@@ -0,0 +1,60 @@
+Maven plugin to generate AssertJ assertions
+==
+
+[](https://maven-badges.herokuapp.com/maven-central/org.assertj/assertj-assertions-generator-maven-plugin)
+
+## Overview
+
+This plugin can generate [AssertJ assertions](https://github.com/joel-costigliola/assertj-core) for your own classes via maven (it is based on [assertj-assertions-generator](https://github.com/joel-costigliola/assertj-assertions-generator)).
+
+Let's say that you have a `Player` class with `name` and `team` attributes, the plugin is able to create a `PlayerAssert` assertions class with `hasName` and `hasTeam` assertions, to write code like :
+
+```java
+assertThat(mvp).hasName("Lebron James").hasTeam("Miami Heat");
+```
+
+The plugin can be launched with command `mvn generate-test-sources` (or simply `mvn test`) or with any IDE that supports maven.
+By default, it generates the assertions source files in `target/generated-test-sources/assertions` as per maven convention (but this can be changed - see below).
+
+
+**Example of plugin execution:**
+
+```
+====================================
+AssertJ assertions generation report
+====================================
+
+--- Generator input parameters ---
+
+Generating AssertJ assertions for classes in following packages and subpackages:
+- org.assertj.examples.data
+
+--- Generator results ---
+
+Directory where custom assertions files have been generated :
+- /home/joe/assertj/assertj-examples/target/generated-test-sources/assertj-assertions
+
+Custom assertions files generated :
+- TeamAssert.java
+- BasketBallPlayerAssert.java
+- EmployeeAssert.java
+- NameAssert.java
+- MagicalAssert.java
+- PersonAssert.java
+- RaceAssert.java
+- GameServiceAssert.java
+- MansionAssert.java
+- TitleAssert.java
+- AlignmentAssert.java
+- TolkienCharacterAssert.java
+- RingAssert.java
+- MovieAssert.java
+- TeamManagerAssert.java
+
+Assertions entry point class has been generated in file:
+- /home/joe/assertj/assertj-examples/target/generated-test-sources/assertj-assertions/org/assertj/examples/data/Assertions.java
+```
+
+## Documentation
+
+Please have a look at the complete documentation in [**assertj.org assertions generator section**](http://joel-costigliola.github.io/assertj/assertj-assertions-generator-maven-plugin.html), including a [**quickstart guide**](http://joel-costigliola.github.io/assertj/assertj-assertions-generator-maven-plugin.html#quickstart).
diff --git a/assertj-generator-maven-plugin/javadoc-theme/assertj-theme.css b/assertj-generator-maven-plugin/javadoc-theme/assertj-theme.css
new file mode 100644
index 0000000..ca3f1de
--- /dev/null
+++ b/assertj-generator-maven-plugin/javadoc-theme/assertj-theme.css
@@ -0,0 +1,39 @@
+:root {
+ /* body, block and code fonts */
+ --body-font-family: Verdana, Geneva, sans-serif;
+ --block-font-family: Verdana, Geneva, serif;
+ /* Text colors for body and block elements */
+ --body-text-color: #000000;
+ --block-text-color: #000000;
+ /* Background colors for various elements */
+ --body-background-color: #edd9a6;
+ --detail-background-color: #edd9a6;
+ /* Colors for navigation bar and table captions */
+ --navbar-background-color: #232323;
+ --navbar-text-color: #edd9a6;
+ /* Background color for subnavigation and various headers */
+ --subnav-background-color: #e5c880;
+ --subnav-link-color: var(--link-color);
+ /* Background and text colors for selected tabs and navigation items */
+ --selected-background-color: #e5c880;
+ --selected-text-color: #000000;
+ --selected-link-color: #861203;
+ /* Background colors for generated tables */
+ --table-header-color: #e7ce8e;
+ --even-row-color: #edd9a6;
+ --odd-row-color: #e9d195;
+ /* Text color for page title */
+ --title-color: #000000;
+ /* Text colors for links */
+ --link-color: #861203;
+ --link-color-active: #641003;
+ /* Table of contents */
+ --toc-background-color: var(--body-background-color);
+ --toc-hover-color: #e9d195;
+ /* Snippet and pre colors */
+ --snippet-background-color: var(--body-background-color);
+ /* Border colors for structural elements and user defined tables */
+ --border-color: #e5c880;
+ /* Search input colors */
+ --search-input-background-color: #edd9a6;
+}
diff --git a/assertj-generator-maven-plugin/javadoc-theme/hljs-theme.css b/assertj-generator-maven-plugin/javadoc-theme/hljs-theme.css
new file mode 100644
index 0000000..1e2e177
--- /dev/null
+++ b/assertj-generator-maven-plugin/javadoc-theme/hljs-theme.css
@@ -0,0 +1,108 @@
+/*
+
+Railscasts-like style (c) Visoft, Inc. (Damien White)
+
+*/
+
+.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ background: #232323;
+ color: #e6e1dc;
+ /* added by us */
+ border-radius:8px;
+}
+
+.hljs-comment,
+.hljs-quote {
+ color: #bc9458;
+ font-style: italic;
+}
+
+.hljs-keyword,
+.hljs-selector-tag {
+ color: #c26230;
+}
+
+.hljs-string,
+.hljs-number,
+.hljs-regexp,
+.hljs-variable,
+.hljs-template-variable {
+ color: #a5c261;
+}
+
+.hljs-subst {
+ color: #519f50;
+}
+
+.hljs-tag,
+.hljs-name {
+ color: #e8bf6a;
+}
+
+.hljs-type {
+ color: #ffc66d;
+}
+
+
+.hljs-symbol,
+.hljs-bullet,
+.hljs-built_in,
+.hljs-builtin-name,
+.hljs-attr,
+.hljs-link {
+ color: #6d9cbe;
+}
+
+.hljs-params {
+ color: #d0d0ff;
+}
+
+.hljs-attribute {
+ color: #cda869;
+}
+
+.hljs-meta {
+ color: #9b859d;
+}
+
+.hljs-title,
+.hljs-section {
+ color: #ffc66d;
+}
+
+.hljs-addition {
+ background-color: #144212;
+ color: #e6e1dc;
+ display: inline-block;
+ width: 100%;
+}
+
+.hljs-deletion {
+ background-color: #600;
+ color: #e6e1dc;
+ display: inline-block;
+ width: 100%;
+}
+
+.hljs-selector-class {
+ color: #9b703f;
+}
+
+.hljs-selector-id {
+ color: #8b98ab;
+}
+
+.hljs-emphasis {
+ font-style: italic;
+}
+
+.hljs-strong {
+ font-weight: bold;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
diff --git a/assertj-generator-maven-plugin/pom.xml b/assertj-generator-maven-plugin/pom.xml
new file mode 100644
index 0000000..7e09361
--- /dev/null
+++ b/assertj-generator-maven-plugin/pom.xml
@@ -0,0 +1,160 @@
+
+
+ 4.0.0
+
+
+ org.assertj
+ assertj-generator-build
+ 3.0.0-SNAPSHOT
+
+
+ assertj-generator-maven-plugin
+
+ Maven plugin for AssertJ assertions generator
+
+
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.7
+ 1.7
+
+
+
+ maven-plugin-plugin
+ 3.2
+
+ assertj
+
+ true
+
+
+
+ mojo-descriptor
+
+ descriptor
+
+
+
+ help-goal
+
+ helpmojo
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ org/assertj/maven/HelpMojo.class
+ org/assertj/maven/NoLog.class
+
+
+
+
+
+ maven-surefire-plugin
+
+ ${argLine}
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+ [3.2,)
+
+ descriptor
+ helpmojo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.assertj
+ assertj-assertions-generator
+ 2.2.0
+
+
+ org.assertj
+ assertj-core
+ [2.0.0, 2.99.0]
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+ commons-io
+ commons-io
+ 2.7
+
+
+
+
+ org.apache.maven
+ maven-plugin-api
+ 2.2.1
+
+
+ org.apache.maven
+ maven-project
+ 2.2.1
+
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+ 3.2
+ provided
+
+
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ junit
+ junit
+ test
+
+
+
+
diff --git a/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojo.java b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojo.java
new file mode 100644
index 0000000..2e469ba
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojo.java
@@ -0,0 +1,317 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static java.lang.String.format;
+import static org.apache.commons.io.FileUtils.write;
+import static org.apache.commons.lang3.ArrayUtils.isEmpty;
+import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
+import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_TEST_SOURCES;
+import static org.apache.maven.plugins.annotations.ResolutionScope.TEST;
+import static org.assertj.assertions.generator.AssertionsEntryPointType.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.assertj.core.util.VisibleForTesting;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Generates custom AssertJ assertions (*Assert) for all given classes and classes of given packages.
+ */
+@Mojo(name = "generate-assertions", defaultPhase = GENERATE_TEST_SOURCES, requiresDependencyResolution = TEST, requiresProject = true)
+public class AssertJAssertionsGeneratorMojo extends AbstractMojo {
+
+ private static final String[] INCLUDE_ALL_CLASSES = { ".*" };
+
+ private static final NoLog NO_LOG = new NoLog();
+ /**
+ * Current maven project
+ */
+ @Parameter(property = "project", required = true, readonly = true)
+ public MavenProject project;
+
+ /**
+ * Destination dir to store generated assertion source files.
+ * Defaults to 'target/generated-test-sources/assertj-assertions'.
+ * Your IDE should be able to pick up files from this location as sources automatically when generated.
+ */
+ @Parameter(defaultValue = "${project.build.directory}/generated-test-sources/assertj-assertions", property = "assertj.targetDir")
+ public String targetDir;
+
+ /**
+ *
Package where generated assertion classes will reside.
+ *
+ * If not set (or set to empty), each assertion class is generated in the package of the corresponding class to assert.
+ * For example the generated assertion class for com.nba.Player will be com.nba.PlayerAssert (in the same package as Player).
+ * Defaults to ''.
+ *
+ *
Note that the Assertions entry point classes package is controlled by the entryPointClassPackage property.
+ */
+ @Parameter(defaultValue = "", property = "assertj.generateAssertionsInPackage")
+ public String generateAssertionsInPackage;
+
+ /**
+ * Flag specifying whether to clean the directory where assertions are generated. The default is false.
+ */
+ @Parameter(defaultValue = "false", property = "assertj.cleanTargetDir")
+ public boolean cleanTargetDir;
+
+ /**
+ * The scope of generates sources ('test' or 'compile') to be added to the maven build.
+ * Expected to be used in conjunction with {@link #targetDir}, for example:
+ *
+ * Defaults to 'test'.
+ */
+ @Parameter(defaultValue = "test", property = "assertj.generatedSourcesScope")
+ public String generatedSourcesScope;
+
+ /**
+ * List of packages to generate assertions for.
+ */
+ @Parameter(property = "assertj.packages")
+ public String[] packages;
+
+ /**
+ * List of classes to generate assertions for.
+ */
+ @Parameter(property = "assertj.classes")
+ public String[] classes;
+
+ /**
+ * Generated assertions are limited to classes matching one of the given regular expressions, default is to include
+ * all classes.
+ */
+ @Parameter(property = "assertj.includes")
+ public String[] includes = INCLUDE_ALL_CLASSES;
+
+ /**
+ * If class matches one of the given regex, no assertions will be generated for it, default is not to exclude
+ * anything.
+ */
+ @Parameter(property = "assertj.excludes")
+ public String[] excludes = new String[0];
+
+ /**
+ * Flag specifying whether to generate hierarchical assertions. The default is false.
+ */
+ @Parameter(defaultValue = "true", property = "assertj.hierarchical")
+ public boolean hierarchical;
+
+ /**
+ * Flag specifying whether to generate assertions for all fields (including non public ones). The default is false.
+ */
+ @Parameter(defaultValue = "false", property = "assertj.generateAssertionsForAllFields")
+ public boolean generateAssertionsForAllFields;
+
+ /**
+ * An optional package name for the Assertions entry point class. If omitted, the package will be determined
+ * heuristically from the generated assertions.
+ */
+ @Parameter(property = "assertj.entryPointClassPackage")
+ public String entryPointClassPackage;
+
+ /**
+ * Skip generating classes, handy way to disable the plugin.
+ */
+ @Parameter(property = "assertj.skip")
+ public boolean skip = false;
+
+ /**
+ * Generate Assertions entry point class.
+ */
+ @Parameter(property = "assertj.generate.Assertions")
+ public boolean generateAssertions = true;
+
+ /**
+ * Generate generating BDD Assertions entry point class.
+ */
+ @Parameter(property = "assertj.generate.BddAssertions")
+ public boolean generateBddAssertions = true;
+
+ /**
+ * Generate generating JUnit Soft Assertions entry point class.
+ */
+ @Parameter(property = "assertj.generate.JUnitSoftAssertions")
+ public boolean generateJUnitSoftAssertions = true;
+
+ /**
+ * Generate generating Soft Assertions entry point class.
+ */
+ @Parameter(property = "assertj.generate.SoftAssertions")
+ public boolean generateSoftAssertions = true;
+
+ /**
+ * Do not log anything if true, false by default.
+ */
+ @Parameter(property = "assertj.quiet")
+ public boolean quiet = false;
+
+ /**
+ * The generated assertions report is written to the given file, if given a relative path the root path is where the plugin is executed.
+ */
+ @Parameter(property = "assertj.writeReportInFile")
+ public String writeReportInFile;
+
+ /**
+ * Generate generating Soft Assertions entry point class.
+ */
+ @Parameter(property = "assertj.templates")
+ public Templates templates;
+
+ /**
+ * Generate assertions for package private classes if true
+ */
+ @Parameter(property = "assertj.includePackagePrivateClasses")
+ public boolean includePackagePrivateClasses = false;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (skip) {
+ getLog().info("Assertions generator is disabled as 'skip' option is true.");
+ return;
+ }
+ failIfMojoParametersAreMissing();
+ try {
+ ClassLoader projectClassLoader = getProjectClassLoader();
+ AssertionsGenerator assertionGenerator = new AssertionsGenerator(projectClassLoader);
+ assertionGenerator.generateAssertionsForAllFields(this.generateAssertionsForAllFields);
+ assertionGenerator.setIncludePatterns(includes);
+ assertionGenerator.setExcludePatterns(excludes);
+ if (generateAssertions) assertionGenerator.enableEntryPointClassesGenerationFor(STANDARD);
+ if (generateBddAssertions) assertionGenerator.enableEntryPointClassesGenerationFor(BDD);
+ if (generateSoftAssertions) assertionGenerator.enableEntryPointClassesGenerationFor(SOFT);
+ if (generateJUnitSoftAssertions) {
+ if (junitFoundBy(projectClassLoader)) assertionGenerator.enableEntryPointClassesGenerationFor(JUNIT_SOFT);
+ else
+ getLog().info("JUnit not found in project classpath => JUnitSoftAssertions entry point class won't be generated.");
+ }
+ assertionGenerator.setLog(getLog());
+ if (generateAssertionsInPackage != null) {
+ // user has set generateAssertionsInPackage (not that maven converts empty string param to null)
+ assertionGenerator.setGeneratedAssertionsPackage(generateAssertionsInPackage);
+ }
+ if (cleanTargetDir) cleanPreviouslyGeneratedSources();
+ executeWithAssertionGenerator(assertionGenerator);
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public Log getLog() {
+ return quiet ? NO_LOG : super.getLog();
+ }
+
+ private void cleanPreviouslyGeneratedSources() {
+ try {
+ Path targetDirPath = Paths.get(targetDir);
+ if (Files.exists(targetDirPath) && targetDirPath.toFile().list().length > 0) {
+ getLog().info("Removing previously generated sources in " + targetDir);
+ FileUtils.cleanDirectory(targetDirPath.toFile());
+ }
+ } catch (IOException e) {
+ getLog().warn("Fail to remove previously generated sources in " + targetDir, e);
+ }
+ }
+
+ @VisibleForTesting
+ AssertionsGeneratorReport executeWithAssertionGenerator(AssertionsGenerator assertionGenerator) {
+ if (classes == null) classes = new String[0];
+ AssertionsGeneratorReport generatorReport = assertionGenerator.generateAssertionsFor(packages, classes, targetDir,
+ entryPointClassPackage, hierarchical,
+ templates, includePackagePrivateClasses);
+ printReport(generatorReport);
+ if (isEmpty(generatedSourcesScope) || equalsIgnoreCase("test", generatedSourcesScope)) project.addTestCompileSourceRoot(targetDir);
+ else if (equalsIgnoreCase("compile", generatedSourcesScope)) project.addCompileSourceRoot(targetDir);
+ else getLog().warn(format("Unknown generated sources scope '%s' - no sources added to project", generatedSourcesScope));
+ return generatorReport;
+ }
+
+ private void printReport(AssertionsGeneratorReport assertionsGeneratorReport) {
+ String reportContent = assertionsGeneratorReport.getReportContent();
+ if (shouldWriteReportInFile()) {
+ getLog().info("Writing the assertions generator report in file: " + writeReportInFile);
+ writeReportInFile(reportContent);
+ } else {
+ getLog().info(reportContent);
+ }
+ }
+
+ private void writeReportInFile(String reportContent) {
+ try {
+ write(new File(writeReportInFile), reportContent, UTF_8);
+ } catch (IOException e) {
+ getLog().warn("Failed to write the assertions generation assertionsGeneratorReport in file "
+ + writeReportInFile, e);
+ }
+ }
+
+ private boolean shouldWriteReportInFile() {
+ return writeReportInFile != null;
+ }
+
+ private void failIfMojoParametersAreMissing() throws MojoFailureException {
+ if (isEmpty(packages) && isEmpty(classes)) {
+ throw new MojoFailureException(shouldHaveNonEmptyPackagesOrClasses());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private ClassLoader getProjectClassLoader() throws DependencyResolutionRequiredException, MalformedURLException {
+ List classpathElements = new ArrayList(project.getCompileClasspathElements());
+ classpathElements.addAll(project.getTestClasspathElements());
+ List classpathElementUrls = new ArrayList<>(classpathElements.size());
+ for (String classpathElement : classpathElements) {
+ classpathElementUrls.add(new File(classpathElement).toURI().toURL());
+ }
+ return new URLClassLoader(classpathElementUrls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader());
+ }
+
+ @VisibleForTesting
+ static String shouldHaveNonEmptyPackagesOrClasses() {
+ return format(
+ "Parameter 'packages' or 'classes' must be set to generate assertions.%n[Help] https://github.com/joel-costigliola/assertj-assertions-generator-maven-plugin");
+ }
+
+ private boolean junitFoundBy(ClassLoader projectClassLoader) {
+ try {
+ Class.forName("org.junit.Rule", false, projectClassLoader);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+}
diff --git a/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGenerator.java b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGenerator.java
new file mode 100644
index 0000000..39ece2d
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGenerator.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static com.google.common.collect.Sets.newLinkedHashSet;
+import static org.apache.commons.collections.CollectionUtils.subtract;
+import static org.apache.commons.lang3.ArrayUtils.addAll;
+import static org.assertj.assertions.generator.util.ClassUtil.collectClasses;
+import static org.assertj.core.util.Arrays.isNullOrEmpty;
+import static org.assertj.core.util.Sets.newHashSet;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import com.google.common.reflect.TypeToken;
+import org.apache.maven.plugin.logging.Log;
+import org.assertj.assertions.generator.AssertionsEntryPointType;
+import org.assertj.assertions.generator.BaseAssertionGenerator;
+import org.assertj.assertions.generator.Template;
+import org.assertj.assertions.generator.description.ClassDescription;
+import org.assertj.assertions.generator.description.converter.ClassToClassDescriptionConverter;
+import org.assertj.core.util.VisibleForTesting;
+
+/**
+ * Is able to generate AssertJ assertions classes from packages.
+ */
+public class AssertionsGenerator {
+
+ private static final Pattern INCLUDE_EVERYTHING = Pattern.compile(".*");
+ private ClassToClassDescriptionConverter converter;
+ private ClassLoader classLoader;
+ private BaseAssertionGenerator generator;
+ private Pattern[] includePatterns;
+ private Pattern[] excludePatterns;
+ private Log log;
+ private Set assertionsEntryPointToGenerate;
+
+ public AssertionsGenerator(ClassLoader classLoader) throws IOException {
+ this.generator = new BaseAssertionGenerator();
+ this.converter = new ClassToClassDescriptionConverter();
+ this.classLoader = classLoader;
+ this.includePatterns = new Pattern[] { INCLUDE_EVERYTHING };
+ this.excludePatterns = new Pattern[0];
+ this.assertionsEntryPointToGenerate = newHashSet();
+ }
+
+ public void setIncludePatterns(String[] includeRegexs) {
+ if (isNullOrEmpty(includeRegexs)) {
+ includePatterns = new Pattern[] { INCLUDE_EVERYTHING };
+ return;
+ }
+ includePatterns = new Pattern[includeRegexs.length];
+ for (int i = 0; i < includeRegexs.length; i++) {
+ includePatterns[i] = Pattern.compile(includeRegexs[i]);
+ }
+ }
+
+ public void setExcludePatterns(String[] excludeRegexs) {
+ if (isNullOrEmpty(excludeRegexs)) {
+ return;
+ }
+ excludePatterns = new Pattern[excludeRegexs.length];
+ for (int i = 0; i < excludeRegexs.length; i++) {
+ excludePatterns[i] = Pattern.compile(excludeRegexs[i]);
+ }
+ }
+
+ /**
+ * Generates custom assertions for classes in given packages with the Assertions class entry point in given
+ * destination dir.
+ *
+ * @param inputPackages the packages containing the classes we want to generate Assert classes for.
+ * @param inputClassNames the packages containing the classes we want to generate Assert classes for.
+ * @param destDir the base directory where the classes are going to be generated.
+ * @param entryPointFilePackage the package of the assertions entry point class, may be null.
+ * @param includePackagePrivateClasses collect package private classes if true.
+ */
+ @SuppressWarnings("unchecked")
+ public AssertionsGeneratorReport generateAssertionsFor(String[] inputPackages, String[] inputClassNames,
+ String destDir, String entryPointFilePackage, boolean hierarchical,
+ Templates userTemplates, boolean includePackagePrivateClasses) {
+ generator.setDirectoryWhereAssertionFilesAreGenerated(new File(destDir));
+ AssertionsGeneratorReport report = new AssertionsGeneratorReport();
+ report.setDirectoryPathWhereAssertionFilesAreGenerated(destDir);
+ registerUserTemplates(userTemplates, report);
+ Set classDescriptions = new HashSet<>();
+ report.setInputPackages(inputPackages);
+ report.setInputClasses(inputClassNames);
+ try {
+ Set> classes = collectClasses(classLoader, includePackagePrivateClasses, addAll(inputPackages, inputClassNames));
+ report.reportInputClassesNotFound(classes, inputClassNames);
+ Set> filteredClasses = removeAssertClasses(classes);
+ removeClassesAccordingToIncludeAndExcludePatterns(filteredClasses);
+ report.setExcludedClassesFromAssertionGeneration(subtract(classes, filteredClasses));
+ if (hierarchical) {
+ for (TypeToken> clazz : filteredClasses) {
+ ClassDescription classDescription = converter.convertToClassDescription(clazz);
+ File[] generatedCustomAssertionFiles = generator.generateHierarchicalCustomAssertionFor(classDescription,
+ filteredClasses);
+ report.addGeneratedAssertionFile(generatedCustomAssertionFiles[0]);
+ report.addGeneratedAssertionFile(generatedCustomAssertionFiles[1]);
+ classDescriptions.add(classDescription);
+ }
+ } else {
+ for (TypeToken> clazz : filteredClasses) {
+ ClassDescription classDescription = converter.convertToClassDescription(clazz);
+ File generatedCustomAssertionFile = generator.generateCustomAssertionFor(classDescription);
+ report.addGeneratedAssertionFile(generatedCustomAssertionFile);
+ classDescriptions.add(classDescription);
+ }
+ }
+
+ for (AssertionsEntryPointType assertionsEntryPointType : assertionsEntryPointToGenerate) {
+ File assertionsEntryPointFile = generator.generateAssertionsEntryPointClassFor(classDescriptions,
+ assertionsEntryPointType,
+ entryPointFilePackage);
+ report.reportEntryPointGeneration(assertionsEntryPointType, assertionsEntryPointFile);
+ }
+ } catch (Exception e) {
+ report.setException(e);
+ }
+ return report;
+ }
+
+ private void registerUserTemplates(Templates userTemplates, AssertionsGeneratorReport report) {
+ if (userTemplates == null) return;
+ for (Template template : userTemplates.getTemplates(report)) {
+ generator.register(template);
+ }
+ }
+
+ private void removeClassesAccordingToIncludeAndExcludePatterns(Set> filteredClasses) {
+ for (Iterator> it = filteredClasses.iterator(); it.hasNext();) {
+ TypeToken> element = it.next();
+ if (!isIncluded(element) || isExcluded(element)) it.remove();
+ }
+ }
+
+ private boolean isIncluded(TypeToken> element) {
+ String className = element.getRawType().getName();
+ for (Pattern includePattern : includePatterns) {
+ if (includePattern.matcher(className).matches()) return true;
+ }
+ log.debug("Won't generate assertions for " + className + " as it does not match any include regex.");
+ return false;
+ }
+
+ private boolean isExcluded(TypeToken> element) {
+ String className = element.getRawType().getName();
+ for (Pattern excludePattern : excludePatterns) {
+ if (excludePattern.matcher(className).matches()) {
+ log.debug("Won't generate assertions for " + className + " as it matches exclude regex : " + excludePattern);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Set> removeAssertClasses(Set> classList) {
+ Set> filteredClassList = newLinkedHashSet();
+ for (TypeToken> clazz : classList) {
+ String classSimpleName = clazz.getRawType().getSimpleName();
+ if (!classSimpleName.endsWith("Assert") && !classSimpleName.endsWith("Assertions")) {
+ filteredClassList.add(clazz);
+ }
+ }
+ return filteredClassList;
+ }
+
+ @VisibleForTesting
+ public void setBaseGenerator(BaseAssertionGenerator generator) {
+ this.generator = generator;
+ }
+
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
+ public void enableEntryPointClassesGenerationFor(AssertionsEntryPointType type) {
+ this.assertionsEntryPointToGenerate.add(type);
+ }
+
+ public void generateAssertionsForAllFields(boolean generateAssertionsForAllFields) {
+ this.generator.setGenerateAssertionsForAllFields(generateAssertionsForAllFields);
+ }
+
+ public void setGeneratedAssertionsPackage(String generateAssertionsInPackage) {
+ this.generator.setGeneratedAssertionsPackage(generateAssertionsInPackage);
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGeneratorReport.java b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGeneratorReport.java
new file mode 100644
index 0000000..bf115f8
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/AssertionsGeneratorReport.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static com.google.common.collect.Maps.newTreeMap;
+import static com.google.common.collect.Sets.newTreeSet;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.apache.commons.lang3.ArrayUtils.isNotEmpty;
+import static org.apache.commons.lang3.StringUtils.remove;
+import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.reflect.TypeToken;
+import org.assertj.assertions.generator.AssertionsEntryPointType;
+
+public class AssertionsGeneratorReport {
+
+ private static final String INDENT = "- ";
+ private static final String SECTION_START = "--- ";
+ private static final String SECTION_END = " ---\n";
+ private String directoryPathWhereAssertionFilesAreGenerated;
+ private Set generatedCustomAssertionFileNames;
+ private Map assertionsEntryPointFilesByType;
+ private String[] inputPackages;
+ private String[] inputClasses;
+ private Exception exception;
+ private Collection> excludedClassesFromAssertionGeneration;
+ private Set inputClassesNotFound;
+ private List userTemplates;
+
+ public AssertionsGeneratorReport() {
+ assertionsEntryPointFilesByType = newTreeMap();
+ generatedCustomAssertionFileNames = newTreeSet();
+ inputClassesNotFound = newTreeSet();
+ directoryPathWhereAssertionFilesAreGenerated = "no directory set";
+ userTemplates = new ArrayList<>();
+ }
+
+ public void setDirectoryPathWhereAssertionFilesAreGenerated(String directory) {
+ this.directoryPathWhereAssertionFilesAreGenerated = directory;
+ }
+
+ public void addGeneratedAssertionFile(File generatedCustomAssertionFile) throws IOException {
+ generatedCustomAssertionFileNames.add(generatedCustomAssertionFile.getCanonicalPath());
+ }
+
+ public String getReportContent() {
+ StringBuilder reportBuilder = new StringBuilder(System.lineSeparator());
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("====================================\n");
+ reportBuilder.append("AssertJ assertions generation report\n");
+ reportBuilder.append("====================================\n");
+ buildGeneratorParametersReport(reportBuilder);
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append(SECTION_START).append("Generator results").append(SECTION_END);
+ if (generationError()) {
+ buildGeneratorReportError(reportBuilder);
+ } else if (nothingGenerated()) {
+ buildGeneratorReportWhenNothingWasGenerated(reportBuilder);
+ } else {
+ buildGeneratorReportSuccess(reportBuilder);
+ }
+ return reportBuilder.toString();
+ }
+
+ private void buildGeneratorReportSuccess(StringBuilder reportBuilder) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("Directory where custom assertions files have been generated:\n");
+ reportBuilder.append(INDENT).append(directoryPathWhereAssertionFilesAreGenerated).append(System.lineSeparator());
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("Custom assertions files generated:\n");
+ for (String fileName : generatedCustomAssertionFileNames) {
+ reportBuilder.append(INDENT).append(fileName).append(System.lineSeparator());
+ }
+ if (!inputClassesNotFound.isEmpty()) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("No custom assertions files generated for the following input classes as they were not found:\n");
+ for (String inputClassNotFound : inputClassesNotFound) {
+ reportBuilder.append(INDENT).append(inputClassNotFound).append(System.lineSeparator());
+ }
+ }
+ reportEntryPointClassesGeneration(reportBuilder);
+ }
+
+ private void reportEntryPointClassesGeneration(StringBuilder reportBuilder) {
+ for (AssertionsEntryPointType type : assertionsEntryPointFilesByType.keySet()) {
+ if (assertionsEntryPointFilesByType.get(type) != null) {
+ String entryPointClassName = remove(type.getFileName(), ".java");
+ reportBuilder.append(System.lineSeparator())
+ .append(entryPointClassName).append(" entry point class has been generated in file:\n")
+ .append(INDENT).append(assertionsEntryPointFilesByType.get(type).getAbsolutePath())
+ .append(System.lineSeparator());
+ }
+ }
+ }
+
+ private void buildGeneratorReportWhenNothingWasGenerated(StringBuilder reportBuilder) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("No assertions generated as no classes have been found from given classes/packages.\n");
+ if (isNotEmpty(inputClasses)) {
+ reportBuilder.append(INDENT).append("Given classes : ").append(Arrays.toString(inputClasses));
+ reportBuilder.append(System.lineSeparator());
+ }
+ if (isNotEmpty(inputPackages)) {
+ reportBuilder.append(INDENT).append("Given packages : ").append(Arrays.toString(inputPackages));
+ reportBuilder.append(System.lineSeparator());
+ }
+ if (isNotEmpty(excludedClassesFromAssertionGeneration)) {
+ reportBuilder.append(INDENT).append("Excluded classes : ").append(excludedClassesFromAssertionGeneration);
+ }
+ }
+
+ private void buildGeneratorReportError(StringBuilder reportBuilder) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("Assertions failed with error : ").append(exception.getMessage());
+ reportBuilder.append(System.lineSeparator());
+ if (isNotEmpty(inputClasses)) {
+ reportBuilder.append(INDENT).append("Given classes were : ").append(Arrays.toString(inputClasses));
+ reportBuilder.append(System.lineSeparator());
+ }
+ if (isNotEmpty(inputPackages)) {
+ reportBuilder.append(INDENT).append("Given packages were : ").append(Arrays.toString(inputPackages));
+ reportBuilder.append(System.lineSeparator());
+ }
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("Full error stack : ").append(getStackTrace(exception));
+ }
+
+ private void buildGeneratorParametersReport(StringBuilder reportBuilder) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append(SECTION_START).append("Generator input parameters").append(SECTION_END)
+ .append(System.lineSeparator());
+ if (isNotEmpty(userTemplates)) {
+ reportBuilder.append("The following templates will replace the ones provided by AssertJ when generating AssertJ assertions :\n");
+ for (String inputPackage : userTemplates) {
+ reportBuilder.append(INDENT).append(inputPackage).append(System.lineSeparator());
+ }
+ reportBuilder.append(System.lineSeparator());
+ }
+ if (isNotEmpty(inputPackages)) {
+ reportBuilder.append("Generating AssertJ assertions for classes in following packages and subpackages:\n");
+ for (String inputPackage : inputPackages) {
+ reportBuilder.append(INDENT).append(inputPackage).append(System.lineSeparator());
+ }
+ }
+ if (isNotEmpty(inputClasses)) {
+ if (isNotEmpty(inputPackages)) {
+ reportBuilder.append(System.lineSeparator());
+ }
+ reportBuilder.append("Generating AssertJ assertions for classes:\n");
+ for (String inputClass : inputClasses) {
+ reportBuilder.append(INDENT).append(inputClass).append(System.lineSeparator());
+ }
+ }
+ if (isNotEmpty(excludedClassesFromAssertionGeneration)) {
+ reportBuilder.append(System.lineSeparator());
+ reportBuilder.append("Input classes excluded from assertions generation:\n");
+ for (TypeToken> excludedClass : excludedClassesFromAssertionGeneration) {
+ reportBuilder.append(INDENT).append(excludedClass.getRawType().getName()).append(System.lineSeparator());
+ }
+ }
+ }
+
+ private boolean generationError() {
+ return exception != null;
+ }
+
+ private boolean nothingGenerated() {
+ return generatedCustomAssertionFileNames.isEmpty();
+ }
+
+ public void reportEntryPointGeneration(AssertionsEntryPointType assertionsEntryPointType,
+ File assertionsEntryPointFile) {
+ this.assertionsEntryPointFilesByType.put(assertionsEntryPointType, assertionsEntryPointFile);
+ }
+
+ public void setInputPackages(String[] packages) {
+ this.inputPackages = packages;
+ }
+
+ public void setInputClasses(String[] classes) {
+ this.inputClasses = classes;
+ }
+
+ public void setException(Exception exception) {
+ this.exception = exception;
+ }
+
+ public Exception getReportedException() {
+ return exception;
+ }
+
+ public void setExcludedClassesFromAssertionGeneration(Collection> excludedClassSet) {
+ this.excludedClassesFromAssertionGeneration = excludedClassSet;
+ }
+
+ public Set getInputClassesNotFound() {
+ return inputClassesNotFound;
+ }
+
+ public void reportInputClassesNotFound(Set> classes, String[] inputClassNames) {
+ Set classesFound = newTreeSet();
+ for (TypeToken> clazz : classes) {
+ classesFound.add(clazz.getRawType().getName());
+ }
+ for (String inputClass : inputClassNames) {
+ if (!classesFound.contains(inputClass)) {
+ inputClassesNotFound.add(inputClass);
+ }
+ }
+ }
+
+ public void registerUserTemplate(String userTemplateDescription) {
+ userTemplates.add(userTemplateDescription);
+ }
+
+ public List getUserTemplates() {
+ return userTemplates;
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/NoLog.java b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/NoLog.java
new file mode 100644
index 0000000..34b2e3a
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/NoLog.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import org.apache.maven.plugin.logging.Log;
+
+public class NoLog implements Log {
+ @Override
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ @Override
+ public void debug(CharSequence content) {
+ // do nothing
+ }
+
+ @Override
+ public void debug(CharSequence content, Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public void debug(Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return false;
+ }
+
+ @Override
+ public void info(CharSequence content) {
+ // do nothing
+ }
+
+ @Override
+ public void info(CharSequence content, Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public void info(Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return false;
+ }
+
+ @Override
+ public void warn(CharSequence content) {
+ // do nothing
+ }
+
+ @Override
+ public void warn(CharSequence content, Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public void warn(Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return false;
+ }
+
+ @Override
+ public void error(CharSequence content) {
+ // do nothing
+ }
+
+ @Override
+ public void error(CharSequence content, Throwable error) {
+ // do nothing
+ }
+
+ @Override
+ public void error(Throwable error) {
+ // do nothing
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/Templates.java b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/Templates.java
new file mode 100644
index 0000000..bd9d8e0
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/main/java/org/assertj/assertions/generator/maven/Templates.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static org.assertj.assertions.generator.Template.Type.ABSTRACT_ASSERT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.ASSERTIONS_ENTRY_POINT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.ASSERTION_ENTRY_POINT;
+import static org.assertj.assertions.generator.Template.Type.ASSERT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.BDD_ASSERTIONS_ENTRY_POINT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.BDD_ENTRY_POINT_METHOD_ASSERTION;
+import static org.assertj.assertions.generator.Template.Type.HAS;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_ARRAY;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_CHAR;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_CHARACTER;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_ITERABLE;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_REAL_NUMBER;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_REAL_NUMBER_WRAPPER;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_WHOLE_NUMBER;
+import static org.assertj.assertions.generator.Template.Type.HAS_FOR_WHOLE_NUMBER_WRAPPER;
+import static org.assertj.assertions.generator.Template.Type.HIERARCHICAL_ASSERT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.IS;
+import static org.assertj.assertions.generator.Template.Type.IS_WRAPPER;
+import static org.assertj.assertions.generator.Template.Type.JUNIT_SOFT_ASSERTIONS_ENTRY_POINT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.SOFT_ASSERTIONS_ENTRY_POINT_CLASS;
+import static org.assertj.assertions.generator.Template.Type.SOFT_ENTRY_POINT_METHOD_ASSERTION;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.assertj.assertions.generator.Template;
+import org.assertj.core.util.Files;
+import org.assertj.core.util.VisibleForTesting;
+
+public class Templates {
+
+ public String templatesDirectory;
+ // assertion class templates
+ public String assertionClass;
+ public String hierarchicalAssertionConcreteClass;
+ public String hierarchicalAssertionAbstractClass;
+ // assertion method templates
+ public String objectAssertion;
+ public String booleanAssertion;
+ public String booleanWrapperAssertion;
+ public String arrayAssertion;
+ public String iterableAssertion;
+ public String charAssertion;
+ public String characterAssertion;
+ public String realNumberAssertion;
+ public String realNumberWrapperAssertion;
+ public String wholeNumberAssertion;
+ public String wholeNumberWrapperAssertion;
+ // entry point templates
+ public String assertionsEntryPointClass;
+ public String assertionEntryPointMethod;
+ public String softEntryPointAssertionClass;
+ public String junitSoftEntryPointAssertionClass;
+ public String softEntryPointAssertionMethod;
+ public String bddEntryPointAssertionClass;
+ public String bddEntryPointAssertionMethod;
+
+ public List getTemplates(AssertionsGeneratorReport report) {
+ // resolve user templates directory
+ if (templatesDirectory == null) templatesDirectory = "./";
+ if (!templatesDirectory.endsWith("/")) templatesDirectory += "/";
+ // load any templates overridden by the user
+ List userTemplates = new ArrayList<>();
+ // @format:off
+ // assertion class templates
+ loadUserTemplate(assertionClass, ASSERT_CLASS, "'class assertions'", userTemplates, report);
+ loadUserTemplate(hierarchicalAssertionConcreteClass, HIERARCHICAL_ASSERT_CLASS, "'hierarchical concrete class assertions'", userTemplates, report);
+ loadUserTemplate(hierarchicalAssertionAbstractClass, ABSTRACT_ASSERT_CLASS, "'hierarchical abstract class assertions'", userTemplates, report);
+ // assertion method templates
+ loadUserTemplate(objectAssertion, HAS, "'object assertions'", userTemplates, report);
+ loadUserTemplate(booleanAssertion, IS, "'boolean assertions'", userTemplates, report);
+ loadUserTemplate(booleanWrapperAssertion, IS_WRAPPER, "'boolean wrapper assertions'", userTemplates, report);
+ loadUserTemplate(arrayAssertion, HAS_FOR_ARRAY, "'array assertions'", userTemplates, report);
+ loadUserTemplate(iterableAssertion, HAS_FOR_ITERABLE, "'iterable assertions'", userTemplates, report);
+ loadUserTemplate(realNumberAssertion, HAS_FOR_REAL_NUMBER, "'real number assertions (float, double)'", userTemplates, report);
+ loadUserTemplate(realNumberWrapperAssertion, HAS_FOR_REAL_NUMBER_WRAPPER, "'real number wrapper assertions (Float, Double)'", userTemplates, report);
+ loadUserTemplate(wholeNumberAssertion, HAS_FOR_WHOLE_NUMBER, "'whole number assertions (int, long, short, byte)'", userTemplates, report);
+ loadUserTemplate(wholeNumberWrapperAssertion, HAS_FOR_WHOLE_NUMBER_WRAPPER, "'whole number has assertions (Integer, Long, Short, Byte)'", userTemplates, report);
+ loadUserTemplate(charAssertion, HAS_FOR_CHAR, "'char assertions'", userTemplates, report);
+ loadUserTemplate(characterAssertion, HAS_FOR_CHARACTER, "'Character assertions'", userTemplates, report);
+ // entry point templates
+ loadUserTemplate(assertionsEntryPointClass,ASSERTIONS_ENTRY_POINT_CLASS, "'assertions entry point class'", userTemplates, report);
+ loadUserTemplate(assertionEntryPointMethod,ASSERTION_ENTRY_POINT, "'assertions entry point method'", userTemplates, report);
+ loadUserTemplate(softEntryPointAssertionClass, SOFT_ASSERTIONS_ENTRY_POINT_CLASS, "'soft assertions entry point class'", userTemplates, report);
+ loadUserTemplate(junitSoftEntryPointAssertionClass, JUNIT_SOFT_ASSERTIONS_ENTRY_POINT_CLASS, "'junit soft assertions entry point class'", userTemplates, report);
+ loadUserTemplate(softEntryPointAssertionMethod, SOFT_ENTRY_POINT_METHOD_ASSERTION, "'soft assertions entry point method'", userTemplates, report);
+ loadUserTemplate(bddEntryPointAssertionClass, BDD_ASSERTIONS_ENTRY_POINT_CLASS, "'BDD assertions entry point class'", userTemplates, report);
+ loadUserTemplate(bddEntryPointAssertionMethod, BDD_ENTRY_POINT_METHOD_ASSERTION, "'BDD assertions entry point method'", userTemplates, report);
+ // @format:on
+ return userTemplates;
+ }
+
+ @VisibleForTesting
+ void loadUserTemplate(String userTemplate, Template.Type type, String templateDescription,
+ List userTemplates, AssertionsGeneratorReport report) {
+ if (userTemplate != null) {
+ try {
+ File templateFile = new File(templatesDirectory, userTemplate);
+ String templateContent = Files.contentOf(templateFile, CharEncoding.UTF_8);
+ userTemplates.add(new Template(type, templateContent));
+ report.registerUserTemplate("Using custom template for " + templateDescription + " loaded from "
+ + templatesDirectory + userTemplate);
+ } catch (@SuppressWarnings("unused") Exception e) {
+ // best effort : if we can't read user template, use the default one.
+ report.registerUserTemplate("Use default " + templateDescription
+ + " assertion template as we failed to read user template from "
+ + templatesDirectory + userTemplate);
+ }
+ }
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojoTest.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojoTest.java
new file mode 100644
index 0000000..65e42e5
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/AssertJAssertionsGeneratorMojoTest.java
@@ -0,0 +1,547 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.contentOf;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+import static org.assertj.core.util.Arrays.array;
+import static org.assertj.core.util.Files.newFile;
+import static org.assertj.core.util.Lists.newArrayList;
+import static org.assertj.assertions.generator.maven.AssertJAssertionsGeneratorMojo.shouldHaveNonEmptyPackagesOrClasses;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.assertj.assertions.generator.BaseAssertionGenerator;
+import org.assertj.assertions.generator.description.ClassDescription;
+import org.assertj.assertions.generator.maven.test.All;
+import org.assertj.assertions.generator.maven.test.Employee;
+import org.assertj.assertions.generator.maven.test.Player;
+import org.assertj.assertions.generator.maven.test.name.Name;
+import org.assertj.assertions.generator.maven.test.name.NameService;
+import org.assertj.assertions.generator.maven.test2.adress.Address;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class AssertJAssertionsGeneratorMojoTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private AssertJAssertionsGeneratorMojo assertjAssertionsGeneratorMojo;
+ private MavenProject mavenProject;
+
+ @Before
+ public void setUp() throws Exception {
+ mavenProject = mock(MavenProject.class);
+ assertjAssertionsGeneratorMojo = new AssertJAssertionsGeneratorMojo();
+ assertjAssertionsGeneratorMojo.project = mavenProject;
+ assertjAssertionsGeneratorMojo.targetDir = temporaryFolder.getRoot().getAbsolutePath();
+ }
+
+ @Test
+ public void executing_plugin_with_classes_and_packages_parameter_only_should_pass() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test", "org.assertj.assertions.generator.maven.test2");
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsFileFor(Address.class)).exists();
+ assertThat(assertionsEntryPointFile("Assertions.java")).exists();
+ assertThat(assertionsEntryPointFile("BddAssertions.java")).exists();
+ assertThat(assertionsEntryPointFile("SoftAssertions.java")).exists();
+ }
+
+ @Test
+ public void executing_plugin_with_hierarchical_option_should_generate_hierarchical_assertions() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test", "org.assertj.assertions.generator.maven.test2");
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.hierarchical = true;
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(abstractAssertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsFileFor(Address.class)).exists();
+ assertThat(abstractAssertionsFileFor(Address.class)).exists();
+ assertThat(assertionsEntryPointFile("Assertions.java")).exists();
+ assertThat(assertionsEntryPointFile("BddAssertions.java")).exists();
+ assertThat(assertionsEntryPointFile("SoftAssertions.java")).exists();
+ }
+
+ @Test
+ public void should_generate_assertions_with_user_templates() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.All");
+ assertjAssertionsGeneratorMojo.templates = new Templates();
+ assertjAssertionsGeneratorMojo.templates.templatesDirectory = "src/test/resources/templates/";
+ assertjAssertionsGeneratorMojo.templates.objectAssertion = "my_has_assertion_template.txt";
+ assertjAssertionsGeneratorMojo.templates.bddEntryPointAssertionMethod = "my_bdd_assertion_entry_point_method_template.txt";
+ assertjAssertionsGeneratorMojo.templates.bddEntryPointAssertionClass = "my_bdd_assertions_entry_point_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.hierarchicalAssertionAbstractClass = "my_custom_abstract_assertion_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.assertionClass = "my_custom_assertion_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.hierarchicalAssertionConcreteClass = "my_custom_hierarchical_assertion_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.characterAssertion = "my_has_assertion_template_for_character.txt";
+ assertjAssertionsGeneratorMojo.templates.charAssertion = "my_has_assertion_template_for_char.txt";
+ assertjAssertionsGeneratorMojo.templates.realNumberAssertion = "my_has_assertion_template_for_real_number.txt";
+ assertjAssertionsGeneratorMojo.templates.realNumberWrapperAssertion = "my_has_assertion_template_for_real_number_wrapper.txt";
+ assertjAssertionsGeneratorMojo.templates.wholeNumberAssertion = "my_has_assertion_template_for_whole_number.txt";
+ assertjAssertionsGeneratorMojo.templates.wholeNumberWrapperAssertion = "my_has_assertion_template_for_whole_number_wrapper.txt";
+ assertjAssertionsGeneratorMojo.templates.arrayAssertion = "my_has_elements_assertion_template_for_array.txt";
+ assertjAssertionsGeneratorMojo.templates.iterableAssertion = "my_has_elements_assertion_template_for_iterable.txt";
+ assertjAssertionsGeneratorMojo.templates.booleanAssertion = "my_is_assertion_template.txt";
+ assertjAssertionsGeneratorMojo.templates.booleanWrapperAssertion = "my_is_wrapper_assertion_template.txt";
+ assertjAssertionsGeneratorMojo.templates.junitSoftEntryPointAssertionClass = "my_junit_soft_assertions_entry_point_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.softEntryPointAssertionMethod = "my_soft_assertion_entry_point_method_template.txt";
+ assertjAssertionsGeneratorMojo.templates.softEntryPointAssertionClass = "my_soft_assertions_entry_point_class_template.txt";
+ assertjAssertionsGeneratorMojo.templates.assertionEntryPointMethod = "my_standard_assertion_entry_point_method_template.txt";
+ assertjAssertionsGeneratorMojo.templates.assertionsEntryPointClass = "my_standard_assertions_entry_point_class_template.txt";
+ List classes = newArrayList(All.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ File allAssertFile = assertionsFileFor(All.class);
+ assertThat(allAssertFile).exists();
+ // check that its content was done using custom templates
+ assertThat(contentOf(allAssertFile)).contains("my_custom_assertion_class_template",
+ "my_has_assertion_template_for_character",
+ "my_has_assertion_template_for_char",
+ "my_has_assertion_template_for_real_number",
+ "my_has_assertion_template_for_real_number_wrapper",
+ "my_has_assertion_template_for_whole_number",
+ "my_has_assertion_template_for_whole_number_wrapper",
+ "my_has_assertion_template",
+ "my_has_elements_assertion_template_for_array",
+ "my_has_elements_assertion_template_for_iterable",
+ "my_is_assertion_template",
+ "my_is_wrapper_assertion_template");
+
+ assertThat(contentOf(assertionsEntryPointFile("Assertions.java"))).contains("my_standard_assertion_entry_point_method_template",
+ "my_standard_assertions_entry_point_class_template");
+ assertThat(contentOf(assertionsEntryPointFile("BddAssertions.java"))).contains("my_bdd_assertion_entry_point_method_template",
+ "my_bdd_assertions_entry_point_class_template");
+ assertThat(contentOf(assertionsEntryPointFile("SoftAssertions.java"))).contains("my_soft_assertion_entry_point_method_template",
+ "my_soft_assertions_entry_point_class_template");
+ assertThat(contentOf(assertionsEntryPointFile("JUnitSoftAssertions.java"))).contains("my_junit_soft_assertions_entry_point_class_template");
+ }
+
+ @Test
+ public void should_not_generate_assertions_for_assert_classes() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.MyAssert");
+ assertjAssertionsGeneratorMojo.packages = array("some.package");
+ assertjAssertionsGeneratorMojo.hierarchical = true;
+ assertjAssertionsGeneratorMojo.execute();
+ assertThat(assertionsFileFor("org.assertj.assertions.generator.maven.test.MyAssertAssert")).doesNotExist();
+ }
+
+ @Test
+ public void should_not_generate_assertions_for_assertions_classes() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.MyAssertions");
+ assertjAssertionsGeneratorMojo.packages = array("some.package");
+ assertjAssertionsGeneratorMojo.execute();
+ assertThat(assertionsFileFor("org.assertj.assertions.generator.maven.test.MyAssertionsAssert")).doesNotExist();
+ }
+
+ @Test
+ public void executing_plugin_with_classes_parameter_only_should_pass() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee",
+ "org.assertj.assertions.generator.maven.test2.adress.Address");
+ List classes = newArrayList(Address.class.getName());
+ assertjAssertionsGeneratorMojo.hierarchical = true;
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsFileFor(Address.class)).exists();
+ assertThat(assertionsEntryPointFile("Assertions.java")).exists();
+ assertThat(assertionsEntryPointFile("BddAssertions.java")).exists();
+ assertThat(assertionsEntryPointFile("SoftAssertions.java")).exists();
+ }
+
+ @Test
+ public void executing_plugin_with_custom_entry_point_class_package_should_pass() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.entryPointClassPackage = "my.custom.pkg";
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFileWithCustomPackage()).exists();
+ }
+
+ @Test
+ public void should_not_generate_entry_point_classes_if_disabled() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ List classes = newArrayList(Employee.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+ assertjAssertionsGeneratorMojo.generateAssertions = false;
+ assertjAssertionsGeneratorMojo.generateBddAssertions = false;
+ assertjAssertionsGeneratorMojo.generateSoftAssertions = false;
+ assertjAssertionsGeneratorMojo.generateJUnitSoftAssertions = false;
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFile("Assertions.java")).doesNotExist();
+ assertThat(assertionsEntryPointFile("BddAssertions.java")).doesNotExist();
+ assertThat(assertionsEntryPointFile("SoftAssertions.java")).doesNotExist();
+ assertThat(assertionsEntryPointFile("JUniSoftAssertions.java")).doesNotExist();
+ }
+
+ @Test
+ public void executing_plugin_with_fake_package_should_not_generate_anything() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("fakepackage");
+ List classes = newArrayList();
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(temporaryFolder.getRoot().list()).isEmpty();
+ }
+
+ @Test
+ public void executing_plugin_with_skip_set_to_true_should_not_generate_anything() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.skip = true;
+ List classes = newArrayList();
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(temporaryFolder.getRoot().list()).isEmpty();
+ }
+
+ @Test
+ public void plugin_should_only_generate_assertions_for_included_classes() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test");
+ assertjAssertionsGeneratorMojo.includes = array(".*Name");
+ List classes = newArrayList(Employee.class.getName(), Name.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(assertionsFileFor(Name.class)).exists();
+ assertThat(assertionsFileFor(NameService.class)).doesNotExist();
+ assertThat(assertionsFileFor(Employee.class)).doesNotExist();
+ }
+
+ @Test
+ public void plugin_should_generate_assertions_for_all_fields() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Player");
+ assertjAssertionsGeneratorMojo.generateAssertionsForAllFields = true;
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(Player.class.getName()));
+
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+
+ // THEN
+ File playerAssertFile = assertionsFileFor(Player.class);
+ assertThat(playerAssertFile).exists();
+ assertThat(contentOf(playerAssertFile)).contains("hasSalary", "hasTeam", "hasName", "isRookie");
+ }
+
+ @Test
+ public void plugin_should_generate_assertions_in_given_package() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Player");
+ assertjAssertionsGeneratorMojo.generateAssertionsInPackage = "my.assertions";
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(Player.class.getName()));
+
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+
+ // THEN
+ File playerAssertFile = new File(temporaryFolder.getRoot(), "my/assertions/PlayerAssert.java");
+ assertThat(playerAssertFile).exists();
+ assertThat(contentOf(playerAssertFile)).contains("package my.assertions");
+ }
+
+ @Test
+ public void plugin_should_not_generate_assertions_for_excluded_classes() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test");
+ assertjAssertionsGeneratorMojo.excludes = array(".*Employee", ".*Service");
+ List classes = newArrayList(Employee.class.getName(), Name.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(assertionsFileFor(Name.class)).exists();
+ assertThat(assertionsFileFor(NameService.class)).doesNotExist();
+ assertThat(assertionsFileFor(Employee.class)).doesNotExist();
+ }
+
+ @Test
+ public void plugin_should_not_generate_any_assertions_as_all_package_classes_are_excluded() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test");
+ assertjAssertionsGeneratorMojo.excludes = array(".*Employ..", ".*Name.*");
+ List classes = newArrayList(Employee.class.getName(), Name.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(assertionsFileFor(Name.class)).doesNotExist();
+ assertThat(assertionsFileFor(NameService.class)).doesNotExist();
+ assertThat(assertionsFileFor(Employee.class)).doesNotExist();
+ }
+
+ @Test
+ public void plugin_should_not_generate_assertions_for_classes_matching_both_include_and_exclude_pattern() throws Exception {
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test");
+ assertjAssertionsGeneratorMojo.includes = array(".*Employee", ".*Name.*");
+ assertjAssertionsGeneratorMojo.excludes = array(".*Employee", ".*Service");
+ List classes = newArrayList(Employee.class.getName(), Name.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+
+ assertjAssertionsGeneratorMojo.execute();
+
+ assertThat(assertionsFileFor(Name.class)).exists();
+ assertThat(assertionsFileFor(NameService.class)).doesNotExist();
+ assertThat(assertionsFileFor(Employee.class)).doesNotExist();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void executing_plugin_with_error_should_be_reported_in_generator_report() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(Employee.class.getName()));
+ // let's throws an IOException when generating custom assertions
+ AssertionsGenerator generator = new AssertionsGenerator(Thread.currentThread().getContextClassLoader());
+ BaseAssertionGenerator baseGenerator = mock(BaseAssertionGenerator.class);
+ generator.setBaseGenerator(baseGenerator);
+ when(baseGenerator.generateCustomAssertionFor(any(ClassDescription.class))).thenThrow(IOException.class);
+ AssertionsGeneratorReport report = assertjAssertionsGeneratorMojo.executeWithAssertionGenerator(generator);
+
+ assertThat(report.getReportedException()).isInstanceOf(IOException.class);
+ assertThat(temporaryFolder.getRoot().list()).isEmpty();
+ }
+
+ @Test
+ public void input_classes_not_found_should_be_listed_in_generator_report() throws Exception {
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee", "org.Foo", "org.Bar");
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(Employee.class.getName()));
+ AssertionsGenerator generator = new AssertionsGenerator(Thread.currentThread().getContextClassLoader());
+
+ AssertionsGeneratorReport report = assertjAssertionsGeneratorMojo.executeWithAssertionGenerator(generator);
+
+ // check that expected assertions file exist (we don't check the content we suppose the generator works).
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(report.getInputClassesNotFound()).as("check report").containsExactly("org.Bar", "org.Foo");
+ }
+
+ @Test
+ public void should_fail_if_packages_and_classes_parameters_are_null() throws Exception {
+ try {
+ assertjAssertionsGeneratorMojo.execute();
+ failBecauseExceptionWasNotThrown(MojoFailureException.class);
+ } catch (MojoFailureException e) {
+ assertThat(e).hasMessage(shouldHaveNonEmptyPackagesOrClasses());
+ }
+ }
+
+ @Test
+ public void should_clean_previously_generated_assertions_before_generating_new_ones() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.cleanTargetDir = true;
+ File shouldBeDeleted = newFile(assertjAssertionsGeneratorMojo.targetDir + "/should-be-deleted");
+ assertThat(shouldBeDeleted).exists();
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(shouldBeDeleted).doesNotExist();
+ }
+
+ @Test
+ public void should_not_clean_previously_generated_assertions_by_default() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test.Employee");
+ File shouldStillExist = newFile(assertjAssertionsGeneratorMojo.targetDir + "/should-still-exist");
+ assertThat(shouldStillExist).exists();
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(shouldStillExist).exists();
+ }
+
+ @Test
+ public void should_not_log_anything() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test.Employee");
+ // WHEN
+ assertjAssertionsGeneratorMojo.quiet = true;
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ // no logs should be produced
+ }
+
+ @Test
+ public void should_write_report_to_file() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.packages = array("org.assertj.assertions.generator.maven.test.Employee");
+ String reportFilename = "target/reportFilename";
+ assertjAssertionsGeneratorMojo.writeReportInFile = reportFilename;
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ File reportFile = new File(reportFilename);
+ assertThat(reportFile).exists();
+ assertThat(contentOf(reportFile)).contains("EmployeeAssert");
+ }
+
+ @Test
+ public void executing_plugin_with_default_target_scope_should_pass() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.entryPointClassPackage = "my.custom.pkg";
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFileWithCustomPackage()).exists();
+ verify(mavenProject).addTestCompileSourceRoot(assertjAssertionsGeneratorMojo.targetDir);
+ }
+
+ @Test
+ public void executing_plugin_with_test_target_scope_should_pass() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.entryPointClassPackage = "my.custom.pkg";
+ assertjAssertionsGeneratorMojo.generatedSourcesScope = "test";
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFileWithCustomPackage()).exists();
+ verify(mavenProject).addTestCompileSourceRoot(assertjAssertionsGeneratorMojo.targetDir);
+ }
+
+ @Test
+ public void executing_plugin_with_compile_target_scope_should_pass() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.entryPointClassPackage = "my.custom.pkg";
+ assertjAssertionsGeneratorMojo.generatedSourcesScope = "compile";
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFileWithCustomPackage()).exists();
+ verify(mavenProject).addCompileSourceRoot(assertjAssertionsGeneratorMojo.targetDir);
+ }
+
+ @Test
+ public void executing_plugin_with_invalid_target_scope_should_pass() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.test.Employee");
+ assertjAssertionsGeneratorMojo.entryPointClassPackage = "my.custom.pkg";
+ assertjAssertionsGeneratorMojo.generatedSourcesScope = "invalid";
+ List classes = newArrayList(Employee.class.getName(), Address.class.getName());
+ when(mavenProject.getCompileClasspathElements()).thenReturn(classes);
+ // WHEN
+ assertjAssertionsGeneratorMojo.execute();
+ // THEN
+ assertThat(assertionsFileFor(Employee.class)).exists();
+ assertThat(assertionsEntryPointFileWithCustomPackage()).exists();
+ verify(mavenProject, never()).addCompileSourceRoot(assertjAssertionsGeneratorMojo.targetDir);
+ verify(mavenProject, never()).addTestCompileSourceRoot(assertjAssertionsGeneratorMojo.targetDir);
+ }
+
+ @Test
+ public void plugin_should_generate_assertions_for_included_package_private_classes_when_option_enabled() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.PackagePrivate");
+ assertjAssertionsGeneratorMojo.includePackagePrivateClasses = true;
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(PackagePrivate.class.getName()));
+ AssertionsGenerator generator = new AssertionsGenerator(Thread.currentThread().getContextClassLoader());
+ // WHEN
+ assertjAssertionsGeneratorMojo.executeWithAssertionGenerator(generator);
+ // THEN
+ assertThat(assertionsFileFor(PackagePrivate.class)).exists();
+ }
+
+ @Test
+ public void plugin_should_not_generate_assertions_for_included_package_private_classes_by_default() throws Exception {
+ // GIVEN
+ assertjAssertionsGeneratorMojo.classes = array("org.assertj.assertions.generator.maven.PackagePrivate");
+ when(mavenProject.getCompileClasspathElements()).thenReturn(newArrayList(PackagePrivate.class.getName()));
+ AssertionsGenerator generator = new AssertionsGenerator(Thread.currentThread().getContextClassLoader());
+ // WHEN
+ assertjAssertionsGeneratorMojo.executeWithAssertionGenerator(generator);
+ // THEN
+ assertThat(assertionsFileFor(PackagePrivate.class)).doesNotExist();
+ }
+
+ private File assertionsFileFor(Class> clazz) {
+ return new File(temporaryFolder.getRoot(), basePathName(clazz) + "Assert.java");
+ }
+
+ private File assertionsFileFor(String className) {
+ return new File(temporaryFolder.getRoot(), className.replace('.', File.separatorChar) + ".java");
+ }
+
+ private File abstractAssertionsFileFor(Class> clazz) {
+ return new File(temporaryFolder.getRoot(), basePathName("Abstract", clazz) + "Assert.java");
+ }
+
+ private static String basePathName(Class> clazz) {
+ return basePathName("", clazz);
+ }
+
+ private static String basePathName(String prefix, Class> clazz) {
+ return clazz.getPackage().getName().replace('.', File.separatorChar) + File.separator + prefix
+ + clazz.getSimpleName();
+ }
+
+ private File assertionsEntryPointFile(String simpleName) {
+ return new File(temporaryFolder.getRoot(), "org.assertj.assertions.generator.maven.test".replace('.', File.separatorChar)
+ + File.separator + simpleName);
+ }
+
+ private File assertionsEntryPointFileWithCustomPackage() {
+ return new File(temporaryFolder.getRoot(), "my.custom.pkg".replace('.', File.separatorChar) + File.separator
+ + "Assertions.java");
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/PackagePrivate.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/PackagePrivate.java
new file mode 100644
index 0000000..86fce33
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/PackagePrivate.java
@@ -0,0 +1,16 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+class PackagePrivate {
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/TemplatesTest.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/TemplatesTest.java
new file mode 100644
index 0000000..f9153dc
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/TemplatesTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.assertj.assertions.generator.Template;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TemplatesTest {
+
+ private AssertionsGeneratorReport report;
+ private Templates templates;
+
+ @Before
+ public void setup() {
+ templates = new Templates();
+ report = new AssertionsGeneratorReport();
+ }
+
+ @Test
+ public void should_load_user_template() {
+ // GIVEN
+ List list = new ArrayList<>();
+ String templateFilename = "my_has_assertion_template.txt";
+ templates.templatesDirectory = "target/test-classes/templates/";
+ // WHEN
+ templates.loadUserTemplate(templateFilename, Template.Type.HAS, "my has template", list, report);
+ // THEN
+ assertThat(list).hasSize(1);
+ assertThat(list.get(0).getContent()).isNotEmpty();
+ assertThat(report.getUserTemplates()).containsOnly("Using custom template for my has template loaded from target/test-classes/templates/my_has_assertion_template.txt");
+ }
+
+ @Test
+ public void should_log_loading_failure_and_move_one() {
+ // GIVEN
+ List list = new ArrayList<>();
+ templates.templatesDirectory = "target/test-classes/templates/";
+ // WHEN
+ templates.loadUserTemplate("unknown", Template.Type.HAS, "my has template", list, report);
+ // THEN
+ assertThat(list).isEmpty();
+ assertThat(report.getUserTemplates()).containsOnly("Use default my has template assertion template as we failed to read user template from target/test-classes/templates/unknown");
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/All.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/All.java
new file mode 100644
index 0000000..30df9c4
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/All.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test;
+
+import static java.util.Arrays.asList;
+
+import java.util.List;
+
+/**
+ * This is a class to test generation of all possible types
+ */
+public class All {
+
+ public boolean isBoolean() {
+ return true;
+ }
+
+ public Boolean isBooleanWrapper() {
+ return null;
+ }
+
+ private Boolean enabled;
+
+ public Boolean isEnabled() {
+ return enabled;
+ }
+
+ public byte getByte() {
+ return 0;
+ }
+
+ public Byte getByteWrapper() {
+ return null;
+ }
+
+ public char getChar() {
+ return 'h';
+ }
+
+ public Character getCharacter() {
+ return 'h';
+ }
+
+ public double getDouble() {
+ return 0.0;
+ }
+
+ public Double getDoubleWrapper() {
+ return 0.0;
+ }
+
+ public float getFloat() {
+ return 1.0f;
+ }
+
+ public Float getFloatWrapper() {
+ return 1.0f;
+ }
+
+ public long getLong() {
+ return 1l;
+ }
+
+ public Long getLongWrapper() {
+ return 1L;
+ }
+
+ public short getShort() {
+ return 1;
+ }
+
+ public Short getShortWrapper() {
+ return 1;
+ }
+
+ public int getInt() {
+ return 1;
+ }
+
+ public Integer getInteger() {
+ return 1;
+ }
+
+ public Object getObject() {
+ return "";
+ }
+
+ public List getBars() {
+ return asList("");
+ }
+
+ public Object[] getFoos() {
+ return new Object[0];
+ }
+
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Employee.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Employee.java
new file mode 100644
index 0000000..e808f64
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Employee.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test;
+
+import java.util.List;
+
+import org.assertj.assertions.generator.maven.test2.adress.Address;
+
+
+public class Employee {
+
+ private String name;
+ private List addresses;
+ private boolean active;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getAddresses() {
+ return addresses;
+ }
+
+ public void setAddresses(List addresses) {
+ this.addresses = addresses;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssert.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssert.java
new file mode 100644
index 0000000..214ec0b
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssert.java
@@ -0,0 +1,17 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test;
+
+public class MyAssert {
+ // empty : just used to test that generator does not generate assertions for Assert classes
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssertions.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssertions.java
new file mode 100644
index 0000000..291ef3a
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/MyAssertions.java
@@ -0,0 +1,17 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test;
+
+public class MyAssertions {
+ // empty : just used to test that generator does not generate assertions for Assertions classes
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Player.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Player.java
new file mode 100644
index 0000000..27a8584
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/Player.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test;
+
+import org.assertj.assertions.generator.maven.test.name.Name;
+
+public class Player {
+ private int salary;
+ protected Name name;
+ String team;
+ public boolean rookie;
+
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/Name.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/Name.java
new file mode 100644
index 0000000..323b597
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/Name.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test.name;
+
+public class Name {
+
+ private String firstName;
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/NameService.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/NameService.java
new file mode 100644
index 0000000..0b825fe
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test/name/NameService.java
@@ -0,0 +1,19 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test.name;
+
+public class NameService {
+
+ // empty : only used for regex testing
+
+}
diff --git a/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test2/adress/Address.java b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test2/adress/Address.java
new file mode 100644
index 0000000..ce423c4
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/java/org/assertj/assertions/generator/maven/test2/adress/Address.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2012-2025 the original author or authors.
+ */
+package org.assertj.assertions.generator.maven.test2.adress;
+
+public class Address {
+
+ private String street;
+ private String city;
+ private Integer flatNo;
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public Integer getFlatNo() {
+ return flatNo;
+ }
+
+ public void setFlatNo(Integer flatNo) {
+ this.flatNo = flatNo;
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertion_entry_point_method_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertion_entry_point_method_template.txt
new file mode 100644
index 0000000..34f8f18
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertion_entry_point_method_template.txt
@@ -0,0 +1,9 @@
+ /** my_bdd_assertion_entry_point_method_template
+ * Creates a new instance of {@link ${custom_assertion_class}}.
+ *
+ * @param actual the actual value.
+ * @return the created assertion object.
+ */
+ public static ${custom_assertion_class} then(${class_to_assert} actual) {
+ return new ${custom_assertion_class}(actual);
+ }
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertions_entry_point_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertions_entry_point_class_template.txt
new file mode 100644
index 0000000..868e65b
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_bdd_assertions_entry_point_class_template.txt
@@ -0,0 +1,15 @@
+package ${package};
+
+/** my_bdd_assertions_entry_point_class_template
+ * Entry point for BDD assertions of different data types. Each method in this class is a static factory for the
+ * type-specific assertion objects.
+ */
+public class BddAssertions {
+${all_assertions_entry_points}
+ /**
+ * Creates a new {@link BddAssertions}.
+ */
+ protected BddAssertions() {
+ // empty
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_abstract_assertion_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_abstract_assertion_class_template.txt
new file mode 100644
index 0000000..af2a1ba
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_abstract_assertion_class_template.txt
@@ -0,0 +1,15 @@
+package ${package};
+
+${imports}
+/** my_custom_abstract_assertion_class_template
+ * Abstract base class for {@link ${class_to_assert}} specific assertions - Generated by CustomAssertionGenerator.
+ */
+public abstract class ${custom_assertion_class}, A extends ${class_to_assert}> extends ${super_assertion_class} {
+
+ /**
+ * Creates a new {@link ${custom_assertion_class}} to make assertions on actual ${class_to_assert}.
+ * @param actual the ${class_to_assert} we want to make assertions on.
+ */
+ protected ${custom_assertion_class}(A actual, Class selfType) {
+ super(actual, selfType);
+ }
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_assertion_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_assertion_class_template.txt
new file mode 100644
index 0000000..629884d
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_assertion_class_template.txt
@@ -0,0 +1,25 @@
+package ${package};
+
+${imports}
+/** my_custom_assertion_class_template
+ * {@link ${class_to_assert}} specific assertions - Generated by CustomAssertionGenerator.
+ */
+public class ${custom_assertion_class} extends AbstractAssert<${custom_assertion_class}, ${class_to_assert}> {
+
+ /**
+ * Creates a new {@link ${custom_assertion_class}} to make assertions on actual ${class_to_assert}.
+ * @param actual the ${class_to_assert} we want to make assertions on.
+ */
+ public ${custom_assertion_class}(${class_to_assert} actual) {
+ super(actual, ${custom_assertion_class}.class);
+ }
+
+ /**
+ * An entry point for ${custom_assertion_class} to follow AssertJ standard assertThat() statements.
+ * With a static import, one can write directly: assertThat(my${class_to_assert}) and get specific assertion with code completion.
+ * @param actual the ${class_to_assert} we want to make assertions on.
+ * @return a new {@link ${custom_assertion_class}}
+ */
+ public static ${custom_assertion_class} assertThat(${class_to_assert} actual) {
+ return new ${custom_assertion_class}(actual);
+ }
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_hierarchical_assertion_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_hierarchical_assertion_class_template.txt
new file mode 100644
index 0000000..08b2b66
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_custom_hierarchical_assertion_class_template.txt
@@ -0,0 +1,29 @@
+package ${package};
+
+
+/** my_custom_hierarchical_assertion_class_template
+ * {@link ${class_to_assert}} specific assertions - Generated by CustomAssertionGenerator.
+ *
+ * Although this class is not final to allow Soft assertions proxy, if you wish to extend it,
+ * extend {@link Abstract${custom_assertion_class}} instead.
+ */
+public class ${custom_assertion_class} extends Abstract${custom_assertion_class}<${custom_assertion_class}, ${class_to_assert}> {
+
+ /**
+ * Creates a new {@link ${custom_assertion_class}} to make assertions on actual ${class_to_assert}.
+ * @param actual the ${class_to_assert} we want to make assertions on.
+ */
+ public ${custom_assertion_class}(${class_to_assert} actual) {
+ super(actual, ${custom_assertion_class}.class);
+ }
+
+ /**
+ * An entry point for ${custom_assertion_class} to follow AssertJ standard assertThat() statements.
+ * With a static import, one can write directly: assertThat(my${class_to_assert}) and get specific assertion with code completion.
+ * @param actual the ${class_to_assert} we want to make assertions on.
+ * @return a new {@link ${custom_assertion_class}}
+ */
+ public static ${custom_assertion_class} assertThat(${class_to_assert} actual) {
+ return new ${custom_assertion_class}(actual);
+ }
+}
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template.txt
new file mode 100644
index 0000000..44f36db
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template.txt
@@ -0,0 +1,23 @@
+
+ /** my_has_assertion_template
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // null safe check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (!Objects.areEqual(actual${Property}, ${property_safe})) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_char.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_char.txt
new file mode 100644
index 0000000..95c947e
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_char.txt
@@ -0,0 +1,23 @@
+
+ /** my_has_assertion_template_for_char
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (actual${Property} != ${property_safe}) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_character.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_character.txt
new file mode 100644
index 0000000..8b4b598
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_character.txt
@@ -0,0 +1,23 @@
+
+ /** my_has_assertion_template_for_character
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // null safe check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (!Objects.areEqual(actual${Property}, ${property_safe})) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive.txt
new file mode 100644
index 0000000..a4c1497
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive.txt
@@ -0,0 +1,23 @@
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (actual${Property} != ${property_safe}) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive_wrapper.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive_wrapper.txt
new file mode 100644
index 0000000..6c5cf25
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_primitive_wrapper.txt
@@ -0,0 +1,23 @@
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // null safe check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (!Objects.areEqual(actual${Property}, ${property_safe})) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number.txt
new file mode 100644
index 0000000..6aa3a32
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number.txt
@@ -0,0 +1,49 @@
+
+ /** my_has_assertion_template_for_real_number
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (actual${Property} != ${property_safe}) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} is close to the given value by less than the given offset.
+ *
+ * If difference is equal to the offset value, assertion is considered successful.
+ * @param ${property_safe} the value to compare the actual ${class_to_assert}'s ${property} to.
+ * @param offset the given offset.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not close enough to the given value.${throws_javadoc}
+ */
+ public ${self_type} has${Property}CloseTo(${propertyType} ${property_safe}, ${propertyType} offset) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ ${propertyType} actual${Property} = actual.get${Property}();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = String.format("\nExpecting ${property}:\n <%s>\nto be close to:\n <%s>\nby less than <%s> but difference was <%s>",
+ actual${Property}, ${property_safe}, offset, Math.abs(${property_safe} - actual${Property}));
+
+ // check
+ Assertions.assertThat(actual${Property}).overridingErrorMessage(assertjErrorMessage).isCloseTo(${property_safe}, Assertions.within(offset));
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number_wrapper.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number_wrapper.txt
new file mode 100644
index 0000000..fc545de
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_real_number_wrapper.txt
@@ -0,0 +1,49 @@
+
+ /** my_has_assertion_template_for_real_number_wrapper
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // null safe check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (!Objects.areEqual(actual${Property}, ${property_safe})) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} is close to the given value by less than the given offset.
+ *
+ * If difference is equal to the offset value, assertion is considered successful.
+ * @param ${property_safe} the value to compare the actual ${class_to_assert}'s ${property} to.
+ * @param offset the given offset.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not close enough to the given value.${throws_javadoc}
+ */
+ public ${self_type} has${Property}CloseTo(${propertyType} ${property_safe}, ${propertyType} offset) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ ${propertyType} actual${Property} = actual.get${Property}();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = String.format("\nExpecting ${property}:\n <%s>\nto be close to:\n <%s>\nby less than <%s> but difference was <%s>",
+ actual${Property}, ${property_safe}, offset, Math.abs(${property_safe} - actual${Property}));
+
+ // check
+ Assertions.assertThat(actual${Property}).overridingErrorMessage(assertjErrorMessage).isCloseTo(${property_safe}, Assertions.within(offset));
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number.txt
new file mode 100644
index 0000000..e327782
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number.txt
@@ -0,0 +1,23 @@
+
+ /** my_has_assertion_template_for_whole_number
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (actual${Property} != ${property_safe}) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number_wrapper.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number_wrapper.txt
new file mode 100644
index 0000000..aa96a76
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_assertion_template_for_whole_number_wrapper.txt
@@ -0,0 +1,23 @@
+
+ /** my_has_assertion_template_for_whole_number_wrapper
+ * Verifies that the actual ${class_to_assert}'s ${property} is equal to the given one.
+ * @param ${property_safe} the given ${property} to compare the actual ${class_to_assert}'s ${property} to.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert}'s ${property} is not equal to the given one.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${propertyType} ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // overrides the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting ${property} of:\n <%s>\nto be:\n <%s>\nbut was:\n <%s>";
+
+ // null safe check
+ ${propertyType} actual${Property} = actual.get${Property}();
+ if (!Objects.areEqual(actual${Property}, ${property_safe})) {
+ failWithMessage(assertjErrorMessage, actual, ${property_safe}, actual${Property});
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_array.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_array.txt
new file mode 100644
index 0000000..5bb7b96
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_array.txt
@@ -0,0 +1,84 @@
+
+ /** my_has_elements_assertion_template_for_array
+ * Verifies that the actual ${class_to_assert}'s ${property} contains the given ${elementType} elements.
+ * @param ${property_safe} the given elements that should be contained in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} does not contain all given ${elementType} elements.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message (use overridingErrorMessage before contains to set your own message).
+ Assertions.assertThat(actual.get${Property}()).contains(${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} contains only the given ${elementType} elements and nothing else in whatever order.
+ *
+ * @param ${property_safe} the given elements that should be contained in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} does not contain all given ${elementType} elements and nothing else.${throws_javadoc}
+ */
+ public ${self_type} hasOnly${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message (use overridingErrorMessage before contains to set your own message).
+ Assertions.assertThat(actual.get${Property}()).containsOnly(${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} does not contain the given ${elementType} elements.
+ *
+ * @param ${property_safe} the given elements that should not be in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} contains any given ${elementType} elements.${throws_javadoc}
+ */
+ public ${self_type} doesNotHave${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message (use overridingErrorMessage before contains to set your own message).
+ Assertions.assertThat(actual.get${Property}()).doesNotContain(${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert} has no ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} is not empty.${throws_javadoc}
+ */
+ public ${self_type} hasNo${Property}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // we override the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting :\n <%s>\nnot to have ${property} but had :\n <%s>";
+
+ // check
+ if (actual.get${Property}().length > 0) {
+ failWithMessage(assertjErrorMessage, actual, java.util.Arrays.toString(actual.get${Property}()));
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_iterable.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_iterable.txt
new file mode 100644
index 0000000..b32dfa2
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_has_elements_assertion_template_for_iterable.txt
@@ -0,0 +1,83 @@
+
+ /** my_has_elements_assertion_template_for_iterable
+ * Verifies that the actual ${class_to_assert}'s ${property} contains the given ${elementType} elements.
+ * @param ${property_safe} the given elements that should be contained in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} does not contain all given ${elementType} elements.${throws_javadoc}
+ */
+ public ${self_type} has${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message, to set another message call: info.overridingErrorMessage("my error message");
+ Iterables.instance().assertContains(info, actual.get${Property}(), ${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} contains only the given ${elementType} elements and nothing else in whatever order.
+ * @param ${property_safe} the given elements that should be contained in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} does not contain all given ${elementType} elements.${throws_javadoc}
+ */
+ public ${self_type} hasOnly${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message, to set another message call: info.overridingErrorMessage("my error message");
+ Iterables.instance().assertContainsOnly(info, actual.get${Property}(), ${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert}'s ${property} does not contain the given ${elementType} elements.
+ *
+ * @param ${property_safe} the given elements that should not be in actual ${class_to_assert}'s ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} contains any given ${elementType} elements.${throws_javadoc}
+ */
+ public ${self_type} doesNotHave${Property}(${elementType}... ${property_safe}) ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check that given ${elementType} varargs is not null.
+ if (${property_safe} == null) failWithMessage("Expecting ${property} parameter not to be null.");
+
+ // check with standard error message (use overridingErrorMessage before contains to set your own message).
+ Iterables.instance().assertDoesNotContain(info, actual.get${Property}(), ${property_safe});
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert} has no ${property}.
+ * @return this assertion object.
+ * @throws AssertionError if the actual ${class_to_assert}'s ${property} is not empty.${throws_javadoc}
+ */
+ public ${self_type} hasNo${Property}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // we override the default error message with a more explicit one
+ String assertjErrorMessage = "\nExpecting :\n <%s>\nnot to have ${property} but had :\n <%s>";
+
+ // check
+ if (actual.get${Property}().iterator().hasNext()) {
+ failWithMessage(assertjErrorMessage, actual, actual.get${Property}());
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_is_assertion_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_is_assertion_template.txt
new file mode 100644
index 0000000..2f8e97f
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_is_assertion_template.txt
@@ -0,0 +1,36 @@
+
+ /** my_is_assertion_template
+ * Verifies that the actual ${class_to_assert} ${predicate_for_javadoc}.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert} ${negative_predicate_for_javadoc}.${throws_javadoc}
+ */
+ public ${self_type} ${predicate}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check
+ if (!actual.${predicate}()) {
+ failWithMessage("\nExpecting that actual ${class_to_assert} ${predicate_for_error_message_part1} but ${predicate_for_error_message_part2}.");
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert} ${negative_predicate_for_javadoc}.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert} ${predicate_for_javadoc}.${throws_javadoc}
+ */
+ public ${self_type} ${neg_predicate}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // check
+ if (actual.${predicate}()) {
+ failWithMessage("\nExpecting that actual ${class_to_assert} ${negative_predicate_for_error_message_part1} but ${negative_predicate_for_error_message_part2}.");
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_is_wrapper_assertion_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_is_wrapper_assertion_template.txt
new file mode 100644
index 0000000..192f6ba
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_is_wrapper_assertion_template.txt
@@ -0,0 +1,36 @@
+
+ /** my_is_wrapper_assertion_template
+ * Verifies that the actual ${class_to_assert} ${predicate_for_javadoc}.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert} ${negative_predicate_for_javadoc}.${throws_javadoc}
+ */
+ public ${self_type} ${predicate}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // null safe check
+ if (Objects.areEqual(Boolean.FALSE, actual.${predicate}())) {
+ failWithMessage("\nExpecting that actual ${class_to_assert} ${predicate_for_error_message_part1} but ${predicate_for_error_message_part2}.");
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
+
+ /**
+ * Verifies that the actual ${class_to_assert} ${negative_predicate_for_javadoc}.
+ * @return this assertion object.
+ * @throws AssertionError - if the actual ${class_to_assert} ${predicate_for_javadoc}.${throws_javadoc}
+ */
+ public ${self_type} ${neg_predicate}() ${throws}{
+ // check that actual ${class_to_assert} we want to make assertions on is not null.
+ isNotNull();
+
+ // null safe check
+ if (Objects.areEqual(Boolean.TRUE, actual.${predicate}())) {
+ failWithMessage("\nExpecting that actual ${class_to_assert} ${negative_predicate_for_error_message_part1} but ${negative_predicate_for_error_message_part2}.");
+ }
+
+ // return the current assertion for method chaining
+ return ${myself};
+ }
\ No newline at end of file
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_junit_soft_assertions_entry_point_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_junit_soft_assertions_entry_point_class_template.txt
new file mode 100644
index 0000000..30f4dcf
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_junit_soft_assertions_entry_point_class_template.txt
@@ -0,0 +1,47 @@
+package ${package};
+
+import org.assertj.core.internal.cglib.proxy.Enhancer;
+
+import org.assertj.core.api.ErrorCollector;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+
+/** my_junit_soft_assertions_entry_point_class_template
+ * Entry point for assertions of different data types. Each method in this class is a static factory for the
+ * type-specific assertion objects.
+ */
+public class JUnitSoftAssertions implements TestRule {
+
+ /** Collects error messages of all AssertionErrors thrown by the proxied method. */
+ protected final ErrorCollector collector = new ErrorCollector();
+
+ /** Creates a new {@link JUnitSoftAssertions}. */
+ public JUnitSoftAssertions() {
+ super();
+ }
+
+ /**
+ * TestRule implementation that verifies that no proxied assertion methods have failed.
+ */
+ public Statement apply(final Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ MultipleFailureException.assertEmpty(collector.errors());
+ }
+ };
+ }
+
+ @SuppressWarnings("unchecked")
+ protected V proxy(Class assertClass, Class actualClass, T actual) {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(assertClass);
+ enhancer.setCallback(collector);
+ return (V) enhancer.create(new Class[] { actualClass }, new Object[] { actual });
+ }
+${all_assertions_entry_points}
+}
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertion_entry_point_method_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertion_entry_point_method_template.txt
new file mode 100644
index 0000000..e0c4750
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertion_entry_point_method_template.txt
@@ -0,0 +1,9 @@
+ /** my_soft_assertion_entry_point_method_template
+ * Creates a new "soft" instance of {@link ${custom_assertion_class}}.
+ *
+ * @param actual the actual value.
+ * @return the created "soft" assertion object.
+ */
+ public ${custom_assertion_class} assertThat(${class_to_assert} actual) {
+ return proxy(${custom_assertion_class}.class, ${class_to_assert}.class, actual);
+ }
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertions_entry_point_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertions_entry_point_class_template.txt
new file mode 100644
index 0000000..d8707b9
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_soft_assertions_entry_point_class_template.txt
@@ -0,0 +1,44 @@
+package ${package};
+
+import static org.assertj.core.groups.Properties.extractProperty;
+
+import java.util.List;
+import org.assertj.core.internal.cglib.proxy.Enhancer;
+
+import org.assertj.core.api.ErrorCollector;
+import org.assertj.core.api.SoftAssertionError;
+
+/** my_soft_assertions_entry_point_class_template
+ * Entry point for assertions of different data types. Each method in this class is a static factory for the
+ * type-specific assertion objects.
+ */
+public class SoftAssertions {
+
+ /** Collects error messages of all AssertionErrors thrown by the proxied method. */
+ protected final ErrorCollector collector = new ErrorCollector();
+
+ /** Creates a new {@link SoftAssertions}. */
+ public SoftAssertions() {
+ }
+
+ /**
+ * Verifies that no proxied assertion methods have failed.
+ *
+ * @throws SoftAssertionError if any proxied assertion objects threw
+ */
+ public void assertAll() {
+ List errors = collector.errors();
+ if (!errors.isEmpty()) {
+ throw new SoftAssertionError(extractProperty("message", String.class).from(errors));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected V proxy(Class assertClass, Class actualClass, T actual) {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(assertClass);
+ enhancer.setCallback(collector);
+ return (V) enhancer.create(new Class[] { actualClass }, new Object[] { actual });
+ }
+${all_assertions_entry_points}
+}
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertion_entry_point_method_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertion_entry_point_method_template.txt
new file mode 100644
index 0000000..d997884
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertion_entry_point_method_template.txt
@@ -0,0 +1,9 @@
+ /** my_standard_assertion_entry_point_method_template
+ * Creates a new instance of {@link ${custom_assertion_class}}.
+ *
+ * @param actual the actual value.
+ * @return the created assertion object.
+ */
+ public static ${custom_assertion_class} assertThat(${class_to_assert} actual) {
+ return new ${custom_assertion_class}(actual);
+ }
diff --git a/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertions_entry_point_class_template.txt b/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertions_entry_point_class_template.txt
new file mode 100644
index 0000000..07acadc
--- /dev/null
+++ b/assertj-generator-maven-plugin/src/test/resources/templates/my_standard_assertions_entry_point_class_template.txt
@@ -0,0 +1,15 @@
+package ${package};
+
+/** my_standard_assertions_entry_point_class_template
+ * Entry point for assertions of different data types. Each method in this class is a static factory for the
+ * type-specific assertion objects.
+ */
+public class Assertions {
+${all_assertions_entry_points}
+ /**
+ * Creates a new {@link Assertions}.
+ */
+ protected Assertions() {
+ // empty
+ }
+}
diff --git a/eclipse/assertj-eclipse-formatter.xml b/eclipse/assertj-eclipse-formatter.xml
new file mode 100644
index 0000000..0c28922
--- /dev/null
+++ b/eclipse/assertj-eclipse-formatter.xml
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 243bfc8..bce6282 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,6 +16,7 @@
assertj-generator
+ assertj-generator-maven-plugin