{"id":37021946,"url":"https://github.com/csoroiu/lambdamatchers","last_synced_at":"2026-01-14T02:36:47.632Z","repository":{"id":54823978,"uuid":"65100154","full_name":"csoroiu/lambdamatchers","owner":"csoroiu","description":"A set of tools that enables creating custom hamcrest matchers more easy. Built with Java 8, usable on Java 8+. ","archived":false,"fork":false,"pushed_at":"2022-08-09T07:18:03.000Z","size":320,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-07-07T14:16:57.986Z","etag":null,"topics":["assert","hamcrest","java","junit","junit5","lambda","matcher","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csoroiu.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}},"created_at":"2016-08-06T20:10:43.000Z","updated_at":"2023-07-06T20:36:02.000Z","dependencies_parsed_at":"2022-08-14T04:00:29.606Z","dependency_job_id":null,"html_url":"https://github.com/csoroiu/lambdamatchers","commit_stats":null,"previous_names":[],"tags_count":19,"template":null,"template_full_name":null,"purl":"pkg:github/csoroiu/lambdamatchers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csoroiu%2Flambdamatchers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csoroiu%2Flambdamatchers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csoroiu%2Flambdamatchers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csoroiu%2Flambdamatchers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csoroiu","download_url":"https://codeload.github.com/csoroiu/lambdamatchers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csoroiu%2Flambdamatchers/sbom","scorecard":{"id":311089,"data":{"date":"2025-08-11","repo":{"name":"github.com/csoroiu/lambdamatchers","commit":"67433984447fecb7b3d44a5614117bd0cb27f2aa"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T23:11:30.303Z","repository_id":54823978,"created_at":"2025-08-17T23:11:30.303Z","updated_at":"2025-08-17T23:11:30.303Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["assert","hamcrest","java","junit","junit5","lambda","matcher","unit-testing"],"created_at":"2026-01-14T02:36:46.986Z","updated_at":"2026-01-14T02:36:47.602Z","avatar_url":"https://github.com/csoroiu.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lambdamatchers\n[![Maven Central][maven-tasks-svg]][maven-tasks-link]\n[![Javadoc][javadoc-svg]][javadoc-link]\n[![Build Status][build-status-svg]][build-status-link]\n[![License][license-svg]][license-link]\n\nThis library implements some hamcrest matchers usable with **Java 8+ (8, 11, 17)** and a set of utility functions built on top of them.\n\n**Les pièces de résistance** are the [LambdaMatchers](https://github.com/csoroiu/lambdamatchers/blob/master/src/main/java/ro/derbederos/hamcrest/LambdaMatchers.java)\n**`hasFeature`** and **`assertFeature`** methods.\n\nThe library is featuring a [MatcherBuilder](https://github.com/csoroiu/lambdamatchers/blob/master/src/main/java/ro/derbederos/hamcrest/MatcherBuilder.java)\nthat enables one to easily create a new custom matcher.\n\n## Features\n* The matchers have meaningful descriptions. The library is intended to be used inside unit test and **help developers to get a better idea of what is wrong before looking at the source code**.\n* The **`assertFeature`** method offers a way to maintain a simple test code while improving the error messages in case of failure.\n* Lambda type detection, thanks to [Type Tools](http://github.com/jhalterman/typetools) library.\n* Works with **Java 8 up to 17**.\n* Compatible with [Hamcrest](https://github.com/hamcrest/JavaHamcrest) 2.2.\n\n## Limitations\n* Does **not** work on **Android** because of the dependencies.\n* Matcher descriptions might not work fine for method references to *unboxing methods*,`Double::doubleValue`.\n* When using agents that instrument the java byte code the type detection might malfunction. \n***In this unfortunate case I encourage you to fill in an issue about the problem you encountered.***\n\n## Usage\n#### Maven test dependency\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ero.derbederos.hamcrest\u003c/groupId\u003e\n    \u003cartifactId\u003elambdamatchers\u003c/artifactId\u003e\n    \u003cversion\u003e0.19\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n#### Gradle test dependency\n```groovy\ntestImplementation 'ro.derbederos.hamcrest:lambdamatchers:0.19'\n```\n\n#### Scala SBT test dependency\n```sbt\nlibraryDependencies += \"ro.derbederos.hamcrest\" % \"lambdamatchers\" % \"0.19\" % \"test\"\n```\n\n\n## Examples\nThe usages of the matchers can be seen in:\n* [RetryAtomic.java](https://gist.github.com/csoroiu/d982344e94b999d08f919737072fde5e)\n* [OptionalMatchers.java](https://gist.github.com/csoroiu/098e51c01f57ecf7b599e7d1fd1b1d96)\n* [LambdaMatchersTest](https://github.com/csoroiu/lambdamatchers/blob/master/src/test/java/ro/derbederos/hamcrest/LambdaMatchersTest.java). Some examples are:\n```java\nassertFeature(person::getName, equalTo(\"Brutus\"));\n\nassertThat(list, everyItem(hasFeature(Person::getAge, greaterThanOrEqualTo(21))));\n\nassertThat(list, hasItem(hasFeature(Person::getName, startsWith(\"Alice\"))));\n\nassertThat(list, featureIterable(Person::getName, hasItem(\"Ana\")));\n\nassertThat(array, featureArray(Person::getName, hasItem(startsWith(\"Ana\"))));\n```\n* [StreamMatchersTest](https://github.com/csoroiu/lambdamatchers/blob/master/src/test/java/ro/derbederos/hamcrest/StreamMatchersTest.java). Some examples are:\n```java\nassertThat(stream, featureStream(Person::getName, hasItem(startsWith(\"Ana\"))));\n\nassertThat(stream, toIterable(hasItem(\"Ana Pop\"));\n\nassertThat(Stream.empty(), emptyStream());\n```\n* [RegexMatchersTest](https://github.com/csoroiu/lambdamatchers/blob/master/src/test/java/ro/derbederos/hamcrest/RegexMatchersTest.java)\n* [RetryMatchersTest](https://github.com/csoroiu/lambdamatchers/blob/master/src/test/java/ro/derbederos/hamcrest/RetryMatchersTest.java). Some examples are:\n```java\nassertThat(mutableObject, retry(500, MutableObjectClass::getValue, equalTo(7)));\n\nassertThat(bean, retry(300, hasProperty(\"value\", equalTo(9))));\n\nassertThat(atomicReferenceSpell, retry(500, AtomicReference::get, powerfulThan(\"Expecto Patronum\")));\n\nassertThat(atomicInteger, retry(300, AtomicInteger::intValue, equalTo(9)));\n\nassertThat(atomicLong, retry(300, AtomicLong::longValue, greaterThan(10L)));\n```\n\nAs already mentioned, this library is intended to be used in tests, and in case of failure, more meaningful descriptions are shown.\n\nSuch an error message for the code:\n```java\nassertFeature(person::getName, equalTo(\"Brutus\"));\n```\ncould be:\n```java\njava.lang.AssertionError: \nExpected: a `Person::getName` \"Brutus\"\n     but: `Person::getName` was \"Caesar\"\n```\n\nAnd for the code:\n```java\nassertThat(list, everyItem(hasFeature(Person::getAge, greaterThanOrEqualTo(22))));\n```\ncould be:\n```java\njava.lang.AssertionError: \nExpected: every item is a Person having `Person::getAge` a value equal to or greater than \u003c22\u003e\n     but: an item `Person::getAge` \u003c21\u003e was less than \u003c22\u003e\n```\n\nAn example a custom matcher creation:\n```java\npublic Matcher\u003cPerson\u003e myCustomMatcher(Person expected) {\n    return MatcherBuilder\n            .of(Person.class)\n            .matches(expected, TestClass::myCustomEquals)\n            .description(expected::getName)\n            .describeMismatch(actual -\u003e \"was \" + actual.getName())\n            .build();\n}\n```\n\n**Happy coding, and most important, happy testing!**\n\n[build-status-svg]: https://app.travis-ci.com/csoroiu/lambdamatchers.svg?branch=master\n[build-status-link]: https://app.travis-ci.com/csoroiu/lambdamatchers\n[javadoc-svg]: http://javadoc.io/badge/ro.derbederos.hamcrest/lambdamatchers.svg?color=red\n[javadoc-link]: http://javadoc.io/doc/ro.derbederos.hamcrest/lambdamatchers\n[license-svg]: https://img.shields.io/badge/license-Apache2-blue.svg\n[license-link]: https://raw.githubusercontent.com/csoroiu/lambdamatchers/master/LICENSE\n[maven-tasks-svg]: https://img.shields.io/maven-central/v/ro.derbederos.hamcrest/lambdamatchers.svg\n[maven-tasks-link]: https://search.maven.org/search?q=g:%22ro.derbederos.hamcrest%22%20AND%20a:%22lambdamatchers%22\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsoroiu%2Flambdamatchers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsoroiu%2Flambdamatchers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsoroiu%2Flambdamatchers/lists"}