{"id":18028217,"url":"https://github.com/llorllale/cactoos-matchers","last_synced_at":"2025-03-27T02:31:13.726Z","repository":{"id":49131430,"uuid":"132507518","full_name":"llorllale/cactoos-matchers","owner":"llorllale","description":"Elegant object-oriented hamcrest matchers ","archived":false,"fork":false,"pushed_at":"2021-06-27T15:15:05.000Z","size":494,"stargazers_count":33,"open_issues_count":11,"forks_count":21,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-22T22:11:26.282Z","etag":null,"topics":["cactoos","elegantobjects","hamcrest-matchers","java","junit","oop","unit-test"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/llorllale.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-07T19:32:13.000Z","updated_at":"2024-12-08T10:32:20.000Z","dependencies_parsed_at":"2022-09-05T14:00:20.942Z","dependency_job_id":null,"html_url":"https://github.com/llorllale/cactoos-matchers","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llorllale%2Fcactoos-matchers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llorllale%2Fcactoos-matchers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llorllale%2Fcactoos-matchers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llorllale%2Fcactoos-matchers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/llorllale","download_url":"https://codeload.github.com/llorllale/cactoos-matchers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245769295,"owners_count":20669156,"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":["cactoos","elegantobjects","hamcrest-matchers","java","junit","oop","unit-test"],"created_at":"2024-10-30T08:14:31.423Z","updated_at":"2025-03-27T02:31:13.364Z","avatar_url":"https://github.com/llorllale.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Managed by Zerocracy](https://www.0crat.com/badge/C63314D6Z.svg)](https://www.0crat.com/p/C63314D6Z)\n[![Donate via Zerocracy](https://www.0crat.com/contrib-badge/C63314D6Z.svg)](https://www.0crat.com/contrib/C63314D6Z)\n\n[![EO principles respected here](http://www.elegantobjects.org/badge.svg)](http://www.elegantobjects.org)\n[![DevOps By Rultor.com](http://www.rultor.com/b/llorllale/cactoos-matchers)](http://www.rultor.com/p/llorllale/cactoos-matchers)\n\n[![Build Status](https://github.com/llorllale/cactoos-matchers/workflows/build/badge.svg)](https://github.com/llorllale/cactoos-matchers/actions)\n[![Javadoc](http://www.javadoc.io/badge/org.llorllale/cactoos-matchers.svg)](http://www.javadoc.io/doc/org.llorllale/cactoos-matchers)\n[![PDD status](http://www.0pdd.com/svg?name=llorllale/cactoos-matchers)](http://www.0pdd.com/p?name=llorllale/cactoos-matchers)\n[![Maven Central](https://img.shields.io/maven-central/v/org.llorllale/cactoos-matchers.svg)](https://maven-badges.herokuapp.com/maven-central/org.llorllale/cactoos-matchers)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/llorllale/cactoos-matchers/blob/master/LICENSE.txt)\n\n[![Test Coverage](https://img.shields.io/codecov/c/github/llorllale/cactoos-matchers.svg)](https://codecov.io/github/llorllale/cactoos-matchers?branch=master)\n[![SonarQube](https://img.shields.io/badge/sonar-ok-green.svg)](https://sonarcloud.io/dashboard?id=org.llorllale%3Acactoos-matchers)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n## What it is\n**cactoos-matchers** is an object-oriented wrapper around hamcrest's matchers.\n\n## Principles\n[Design principles](http://www.elegantobjects.org#principles) behind cactoos-matchers.\n\n## How to use\nThis library depends on [cactoos](https://github.com/yegor256/cactoos) and [hamcrest](https://github.com/hamcrest/JavaHamcrest).\nGet the latest version [here](https://github.com/llorllale/cactoos-matchers/releases):\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.llorllale\u003c/groupId\u003e\n  \u003cartifactId\u003ecactoos-matchers\u003c/artifactId\u003e\n  \u003cversion\u003e${version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nJava version required: 1.8+.\n\n## cactoos-matchers versus Hamcrest + JUnit\n\ncactoos-matchers | Hamcrest (static method) | Hamcrest (object) | JUnit\n------ | ------ | ------ | ------\n`Assertion` | `MatcherAssert.assertThat` | - | `Assert.assertThat`\n`Throws` | - | - | `@expected` + `ExpectedException`\n`EndsWith` | `Matchers.endsWith` | `StringEndsWith` | -\n`StartsWith` | `Matcers.startsWith` | `StringStartsWith` | -\n`TextIs` | `Matchers.is` | `IsEqual` | -\n`HasLines` | - | - | -\n`MatchesRegex` | - | - | -\n`TextHasString` | `Matchers.stringContainsInOrder` | `StringContains` | -\n`FuncApplies` | - | - | -\n`HasValues` | `Matchers.containsInAnyOrder` | `IsIterableContainingInAnyOrder` | -\n`HasValuesMatching` | `Matchers.containsInAnyOrder` | `IsIterableContainingInAnyOrder` | -\n`InputHasContent` | - | - | -\n`IsTrue` | - | - | `Assert.assertTrue`\n`Matches` | - | - | -\n`RunsInThreads` | - | - | -\n`ScalarHasValue` | - | - | -\n\n## How to use\n\nUse our matchers inside your JUnit [`@Test`](http://junit.sourceforge.net/javadoc/org/junit/Test.html) case. We also provide `Assertion\u003cT\u003e` in which you can compose the behavior under test and the test case's matcher, and attempt to affirm it.\n\nWe provide matchers for several different domains:\n\n### Text\nExamples:\n\n```java\n@Test\npublic void textHasPrefix() {\n  final String prefix = \"Application startup\";\n  new Assertion\u003c\u003e(\n    \"must have the prefix\",\n    new TextOf(new File(\"some.log\")),\n    new StartsWith(prefix)\n  ).affirm();\n}  \n\n@Test\npublic void csvLineHasCorrectFormat() throws Exception {\n  final String fields = \"^[^|]+|[^|]+|[^|]+$\";\n  new Assertion\u003c\u003e(\n    \"must match the expected pattern\",\n    new FirstOf\u003c\u003e(\n      line -\u003e true,\n      new Split(\n        new TextOf(new File(\"report.csv\")),\n        \"\\n\"\n      ),\n      () -\u003e new TextOf(\"\")\n    ).value(),\n    new MatchesRegex(fields)\n  ).affirm();\n}\n\n@Test\npublic void textIsBlank(){\n  new Assertion\u003c\u003e(\n    \"must be blank\",\n    new TextOf(\n      new File(\"file.txt\")\n    ),\n    new IsBlank()\n  ).affirm();\n}\n```\n\n### Concurrency\nExamples:\n\n*RunsInThreads*\n```java\n/**\n * Want some assurance that your object is thread-safe?\n */\n@Test\npublic void threadSafety() {\n  new Assertion\u003c\u003e(\n    \"must be able to modify the map concurrently\",\n    map -\u003e {\n      boolean success = true;\n      try {\n        map.forEach(\n          (key, value) -\u003e {\n            map.remove(key);\n            final Random r = new Random();\n            map.put(r.nextInt(), r.nextInt());\n          }\n        );\n      } catch (ConcurrentModificationException ex) {\n        success = false;\n      }\n      return success;\n    },\n    new RunsInThreads\u003c\u003e(new ConcurrentHashMap\u003c\u003e(), 100)\n  ).affirm();\n}\n```\n\n### Matching errors\nExamples:\n\n```java\n@Test\npublic void throwIllegalArgumentExceptionIfLessThan10() throws Exception {\n  final Func\u003cInteger, Integer\u003e test = input -\u003e {\n    if (input \u003c 10) {\n      throw new IllegalArgumentException();\n    }\n    return input * 10;\n  };\n  new Assertion\u003c\u003e(\n    \"must throw illegalargumentexception if input is less than 10\",\n    () -\u003e test.apply(5),\n    new Throws\u003c\u003e(IllegalArgumentException.class)\n  ).affirm();\n}\n```\n\n### Meta-matching: a matcher to test your matchers\nExamples:\n\nUse `Matches` to test matchers themselves:\n\n```java\n@Test\npublic void matchExactString() {\n  new Assertion\u003c\u003e(\n    \"must match the exact text\",\n    new TextIs(\"abc\"),                // matcher being tested\n    new Matches\u003c\u003e(new TextOf(\"abc\"))  // reference against which the matcher is tested\n  ).affirm();\n}\n```\n\n## How to contribute?\n\nJust fork the repo and send us a pull request.\n\nRequest to add yourself to the list of [contributors](#contributors-) below with\nthe [`@all-contributors bot`](https://allcontributors.org/docs/en/bot/usage#all-contributors-add).\n\nMake sure your branch builds without any warnings/issues:\n\n```\nmvn clean install -Pqulice\n```\n\nNote: [Checkstyle](https://en.wikipedia.org/wiki/Checkstyle) is used as a static code analyze tool with\n[checks list](http://checkstyle.sourceforge.net/checks.html) in GitHub precommits.\n\n\n## License (MIT)\n\nCopyright (c) for portions of project cactoos-matchers are held by\nYegor Bugayenko, 2017-2018, as part of project cactoos.\nAll other copyright for project cactoos-matchers are held by\nGeorge Aristy, 2018-2020.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n## Contributors ✨\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://llorllale.github.io/\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/2019896?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGeorge Aristy\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=llorllale\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://www.yegor256.com\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/526301?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYegor Bugayenko\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=yegor256\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://proshin.org\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/3031372?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRoman Proshin\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=proshin-roman\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.linkedin.com/in/lazylead\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/1651114?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYurii Dubinka\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=dgroup\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/andreoss\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/49783909?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eandreoss\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=andreoss\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://www.irit.fr/~Victor.Noel/\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/160975?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eVictor Noël\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=victornoel\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/borysfan\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/1413251?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDominik\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=borysfan\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/scristalli\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/7326295?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eStefano Cristalli\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=scristalli\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/fanifieiev\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/3167940?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eFevzi Anifieiev\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=fanifieiev\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/paulodamaso\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/33915433?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ePaulo Lobo\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=paulodamaso\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Vatavuk\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/2067023?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eVedran Grgo Vatavuk\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=Vatavuk\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://vk.com/sharpler\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/2966206?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlexander\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=SharplEr\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://www.vzurauskas.com\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/18754033?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003evzurauskas\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=vzurauskas\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/jsoroka\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/527688?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ejsoroka\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/llorllale/cactoos-matchers/commits?author=jsoroka\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllorllale%2Fcactoos-matchers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fllorllale%2Fcactoos-matchers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllorllale%2Fcactoos-matchers/lists"}