{"id":20340365,"url":"https://github.com/toolisticon/cute","last_synced_at":"2025-03-17T16:11:56.203Z","repository":{"id":49245436,"uuid":"157887216","full_name":"toolisticon/cute","owner":"toolisticon","description":"Java compile testing library, that allows you to test annotation processors. ","archived":false,"fork":false,"pushed_at":"2025-02-24T02:14:46.000Z","size":729,"stargazers_count":31,"open_issues_count":4,"forks_count":5,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-03-02T14:19:19.413Z","etag":null,"topics":["annotation","annotation-processing","annotation-processor","annotations","compilation-testing","compile","compile-time","hacktoberfest","java","javac","junit","junit4","junit5","processing","processor","test","testing","testng","tests"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/toolisticon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-16T15:38:49.000Z","updated_at":"2025-02-24T02:14:49.000Z","dependencies_parsed_at":"2022-08-24T11:20:49.593Z","dependency_job_id":"e785f343-f02e-4cb3-ab1f-b2a139a4b30c","html_url":"https://github.com/toolisticon/cute","commit_stats":{"total_commits":142,"total_committers":5,"mean_commits":28.4,"dds":"0.30281690140845074","last_synced_commit":"f5b1c8597d4ac96938345efcbed1a69950af11dc"},"previous_names":["toolisticon/compile-testing"],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toolisticon%2Fcute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toolisticon%2Fcute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toolisticon%2Fcute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toolisticon%2Fcute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toolisticon","download_url":"https://codeload.github.com/toolisticon/cute/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244066185,"owners_count":20392406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation","annotation-processing","annotation-processor","annotations","compilation-testing","compile","compile-time","hacktoberfest","java","javac","junit","junit4","junit5","processing","processor","test","testing","testng","tests"],"created_at":"2024-11-14T21:21:28.705Z","updated_at":"2025-03-17T16:11:56.172Z","avatar_url":"https://github.com/toolisticon.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TOOLISTICON CUTE - Compile-Time Unit Testing\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.toolisticon.cute/cute/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.toolisticon.cute/cute)\n![Build Status](https://github.com/toolisticon/cute/workflows/default/badge.svg)\n[![codecov](https://codecov.io/gh/toolisticon/cute/branch/master/graph/badge.svg)](https://codecov.io/gh/toolisticon/cute)\n[![javadoc](https://javadoc.io/badge2/io.toolisticon.cute/cute/javadoc.svg)](https://javadoc.io/doc/io.toolisticon.cute/cute)\n# Why you should use this project?\nTesting of annotation processors can be a very difficult task.\nUsually annotation procecssors are tighly bound to the compile time model of Java and are relying on tools provided by the java compiler during the compilation process.\n\nMocking of both tools and the compile time model is a very difficult task.\nIt's much easier to define testcases as source files and to test your processors during the normal compilation process.\n\nThis compile testing framework allows you to to do this and additionally supports you to provide unit tests for your annotation processor related code in an easy way.\n\n# Features\n\n- allows compile time tests supporting the most relevant test frameworks (junit4, junit5, testng, ...)\n- simple, but powerful fluent api (immutable)\n- additionally provides compilation outcome to do custom assertions with your favorite unit test frameworks.\n- supports all Java versions \u003e=8 (including support for java 9 modules)\n- Enables you to debug annotation processors during compilation tests\n- provides useful information for analysis of failing tests:\n   - error and warning messages\n   - unexpected exceptions\n   - writes generated files to filesystem\n   - test configuration\n- works with most IDEs and compilers\n- dependency-less - binds no 3rd party libraries (therefore no versioning conflicts with your application)\n\n# How does it work?\nSimply add the following dependencies to your project to be able to use this testing framework.\n\n```xml\n\u003cdependencies\u003e\n\n   \u003c!-- Compile testing framework --\u003e\n   \u003cdependency\u003e\n       \u003cgroupId\u003eio.toolisticon.cute\u003c/groupId\u003e\n       \u003cartifactId\u003ecute\u003c/artifactId\u003e\n       \u003cversion\u003e${currentVersion}\u003c/version\u003e\n       \u003cscope\u003etest\u003c/scope\u003e\n   \u003c/dependency\u003e\n    \n   \u003c!-- \n        Legacy API : Only add it if you don't want to use the new API.\n                     or migration to new API isn't an option.\n    --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.toolisticon.cute\u003c/groupId\u003e\n        \u003cartifactId\u003ecute-legacy\u003c/artifactId\u003e\n        \u003cversion\u003e${currentVersion}\u003c/version\u003e\n        \u003cscope\u003etest\u003c/scope\u003e\n    \u003c/dependency\u003e\n   \n   \u003c!-- \n       optional : only needed if you want to trigger assertion \n                  errors via your unit test framework\n       Per default assertion errors are thrown and handled as java.lang.AssertionError by most unit test frameworks.\n   --\u003e\n   \u003cdependency\u003e\n       \u003cgroupId\u003eio.toolisticon.cute\u003c/groupId\u003e\n       \u003cartifactId\u003e${extension-junit4, extension-junit5, extension-testng}\u003c/artifactId\u003e\n       \u003cversion\u003e${currentVersion}\u003c/version\u003e\n       \u003cscope\u003etest\u003c/scope\u003e\n   \u003c/dependency\u003e\n\n\u003c/dependencies\u003e\n```\n     \n# Tests Types\n\nThere are two types of tests: Unit tests and Compilation (or Integration) Tests.\n\nFor both test types you can test\n\n- if compilation was successful or not\n- if certain messages have been created during compilation\n- if certain java files (sources and classes) or resource files have been created\n- if your annotation processor really has been applied (this is implicitly done)\n\nThe CompileTestBuilder always returns immutable CompileTestBuilder instances. \nSo it's safe to initialize a base CompileTestBuilder instance once in a testclass and to refine it further in the testcases.\n\n## Black-Box-Compilation tests\n\nBlack-Box-Compilation test allow you to define testcase source files and to apply your processor on it during its compilation.\n\n```java\n Cute.blackBoxTest()\n    .given()\n        .processor(YourProcessorUnderTest.class)\n        .andSourceFiles(\"/exampletestcase/Testcase1.java\")\n    .whenCompiled()\n    .thenExpectThat()\n        .compilationSucceeds()\n        .andThat()\n            .compilerMessage()\n            .ofKindWarning()\n            .atSource(\"/exampletestcase/Testcase1.java\")\n            .atLine(10L)\n            .atColumn(20L)\n            .contains(\"WARNING SNIPPET(will check if a warning exists that contains passed string)\")\n        .andThat()\n            .generatedSourceFile(\"your.test.package.GeneratedFile\")\n            .matches(\n                CuteApi.ExpectedFileObjectMatcherKind.BINARY,\n                JavaFileObjectUtils.readFromString(\"package your.test.package;\\npublic class GeneratedFile{}\")\n            )\n        .executeTest()\n        .executeCustomAssertions(e -\u003e {\n            // You can do all checks as custom assertions as well :)\n            MatcherAssert.assertThat(\"Compilation should be successful\", e.compilationWasSuccessful());\n            // ...\n        });\n```\n\nAdditionally, to the explicitly configured assertions it implicitly checks if your annotation processor has been applied and triggers an AssertionError if not.\n\n## Unit tests\n\nUsually - if you are developing annotation processors - your code is likely to rely on the tools provided to the annotation processor via the ProcessingEnvironment like Filer, Messager, Types and Elements.\nThese classes and the Java compile time model are hard to mock. That's why unit testing is usually very hard to do.\nThis library helps you to execute unit test at compile time, giving you the ProcessingEnvironment's tools and access to the compile time model for free.\n\nThe unit test concept provided by this library uses a default source file and applies a default annotation processor on it. \nYour unit test code can be declared via the fluent api:\n\n```java\n// a junit 4 example \n// test class should be in same package like your unit under test\n// tested methods must be package visible\n@Test\npublic void exampleUnitTest() {\n\n    Cute.unitTest()\n        .when()\n        .passInProcessor(SampleProcesssor.class)\n        .intoUnitTest( new UnitTestForTestingAnnotationProcessorsWithoutPassIn\u003cSampleProcesssor\u003e() {\n            @Override\n            public void unitTest(SampleProcesssor unit, ProcessingEnvironment processingEnvironment) {\n            \n                // Processor's init() method was called by cute framework\n                String result = unit.yourMethodToTest(\"ABC\");\n            \n                // AssertionErrors will be passed through your external unit test function\n                MatcherAssert.assertThat(result, Matchers.is(\"EXPECTED RESULT\"));\n            \n            }\n        })\n        .thenExpectThat()\n            .compilationSucceeds()\n            .andThat()\n            .compilerMessage()\n                .ofKindWarning()\n                .contains(\"WARNING SNIPPET(will check if a warning exists that contains passed string)\")\n        .executeTest();\n\n}\n```\n \nBesides that it's also possible to add an assertion if an expected exception has been thrown.\n\nAdditionally, you have compile time model access for all classes residing in your classpath (including all test classes), which allows you to setup test classes easily, for example by adding classes to your src/test/java folder or by adding static inner classes to your unit test class.\n\n## Passing elements and annotation processor into unit tests \nAnother cute feature is that it's possible to easily pass in elements and even annotation processors into the unit test. \n\nFor passing in elements all you need to do is to create a static class next to your unit tests and to add the _PassIn_ annotation on the element you want to pass in.\nThe static class then can be used as parameter in _defineTestWithPassedInElement_ method.\n\nAdditionally, you can pass in an annotation processor by using the annotation processor class  as a parameter in _defineTestWithPassedInElement_ method.\nAn instance of the annotation processor will be created and initialized.\n\n```java\nprivate static class PassedInElement {\n    // Add your custom code like\n    @PassIn\n    void yourMethodToBePassedIn(){\n    }\n}\n\n    // Example 1 : Pass in element\n@Test\npublic void yourUnitTestWithPassedInElement() {\n\n    Cute\n        .unitTest()\n        .when().passInElement().\u003cExecutableElement\u003efromClass(PassedInElement.class)\n        .intoUnitTest( new UnitTest\u003cExecutableElement\u003e() {\n            @Override\n            public void unitTest(ProcessingEnvironment processingEnvironment, ExecutableElement element) {\n\n                // put your unit test code\n                // ....\n\n            }\n        })\n        .thenExpectThat()\n        .compilationSucceeds()\n        .executeTest();\n\n\n}\n\n// Example 2 : Pass in annotation processor and element\n// The processor will be instantiated and initialized\n@Test\npublic void yourUnitTestWithPassedInElementAndProcessor() {\n\n    Cute\n        .unitTest()\n        .when()\n        .passInProcessor(YourProcessorToTest.class)\n        .andPassInElement().\u003cExecutableElement\u003efromClass(PassedInElement.class)\n        .intoUnitTest( new UnitTestForTestingAnnotationProcessors\u003cYourProcessorToTest, ExecutableElement\u003e() {\n            @Override\n            public void unitTest(YourProcessorToTest unit, ProcessingEnvironment processingEnvironment, ExecutableElement element) {\n\n                // put your unit test code\n                String result = unit.methodToTest(element);\n                MatcherAssert.assertThat(result, Matchers.is(\"EXPECTED RESULT\"));\n\n            }\n        })\n        .thenExpectThat()\n        .compilationSucceeds()\n        .executeTest();\n\n\n}\n```\n\n### Testing generated and compiled classes\nTesting of the generated code can either be done by providing an integration test project or by using Cute as part of the compilation test.\nUnfortunately, testing generated code with Cute heavily relies on the Javas reflection api, since generated classes aren't available in your unit test code.\nBut it's working flawlessly if your generated classes are implementing precompiled interfaces:\n\n````java\n@Test\npublic void blackBoxTest_justCompileCodeAndDoClassTestWithImplementedInterface() {\n    Cute.blackBoxTest().given().noProcessors()\n        .andSourceFiles(\"/TestClassWithImplementedInterface.java\")\n        .whenCompiled()\n        .thenExpectThat()\n        .compilationSucceeds()\n        .andThat()\n            .generatedClass(\"io.toolisticon.cute.TestClassWithImplementedInterface\")\n            .testedSuccessfullyBy(new GeneratedClassesTestForSpecificClass() {\n                @Override\n                public void doTests(Class\u003c?\u003e clazz, CuteClassLoader cuteClassLoader) throws Exception{\n    \n                    SimpleTestInterface unit = (SimpleTestInterface) clazz.getConstructor().newInstance();\n                    MatcherAssert.assertThat(unit.saySomething(), Matchers.is(\"WHATS UP?\"));\n    \n                }\n            })\n        .executeTest();\n}\n````\n\nConsider to prefer integration tests over Cute if no precompiled interface is implemented by the generated classes.\n\n### Doing unit tests with Java 9 modules involved\nOnce cute detects that a JDK \u003e= 9 is involved and that a module-info.java file is amongst the source files, it will automatically add the automatic cute module to the compilations module path.\n\nNevertheless, the following directive must be added to that module-info.java file to make the unit test work:\n\n```java\nrequires cute;\n```\n\n# Projects using this toolkit library\n\n- [Annotation processor toolkit](https://github.com/toolisticon/annotation-processor-toolkit) : Toolkit that allows you to build annotation processors in a more comfortable way\n- [SPI-AP](https://github.com/toolisticon/SPI-Annotation-Processor) : Annotation processor for generation of spi service locator files\n\n# Alternatives\n\n- [google compile-testing](https://github.com/google/compile-testing): Another library for testing annotation processor at compile time. \n\n# Contributing\n\nWe welcome any kind of suggestions and pull requests.\n\n## Building and developing compile-testing project\n\nThe compile-testing is built using Maven via bundled maven wrapper.\nA simple import of the pom in your IDE should get you up and running. To build the compile-testing project on the commandline, just run `mvnw` or `mvnw clean install`\n\n## Requirements\n\nThe likelihood of a pull request being used rises with the following properties:\n\n- You have used a feature branch.\n- You have included a test that demonstrates the functionality added or fixed.\n- You adhered to the [code conventions](http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).\n\n## Contributions\n\n- (2018) Tobias Stamann (Holisticon AG)\n\n# License\n\nThis project is released under the revised [MIT License](LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoolisticon%2Fcute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoolisticon%2Fcute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoolisticon%2Fcute/lists"}