{"id":13413896,"url":"https://github.com/rdrdr/hamcrest","last_synced_at":"2025-03-14T20:30:43.447Z","repository":{"id":1250767,"uuid":"1189344","full_name":"rdrdr/hamcrest","owner":"rdrdr","description":"Hamcrest matchers for the Go programming language","archived":false,"fork":false,"pushed_at":"2021-01-07T21:29:48.000Z","size":115,"stargazers_count":30,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-31T20:52:57.370Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","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/rdrdr.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":"2010-12-22T04:49:44.000Z","updated_at":"2024-04-11T09:34:25.000Z","dependencies_parsed_at":"2022-08-16T12:45:16.862Z","dependency_job_id":null,"html_url":"https://github.com/rdrdr/hamcrest","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdrdr%2Fhamcrest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdrdr%2Fhamcrest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdrdr%2Fhamcrest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rdrdr%2Fhamcrest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rdrdr","download_url":"https://codeload.github.com/rdrdr/hamcrest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243641974,"owners_count":20323942,"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":[],"created_at":"2024-07-30T20:01:52.228Z","updated_at":"2025-03-14T20:30:43.144Z","avatar_url":"https://github.com/rdrdr.png","language":"Go","readme":"Note:\n=====\nThis has not been maintained and/or updated since 2011.\nPerhaps consider [corbym/gocrest](https://github.com/corbym/gocrest), instead.\n\n\n\nIntroduction\n============\n\nHamcrest is a fluent framework for declarative Matcher objects\nthat, when applied to input values, produce self-describing\nresults.\n\nInstallation:\n========\n\nTo install, run `make install` from the same directory as this\n`README.md` file.\n\nPackages\n========\n\n`hamcrest.go` comes in several packages that you assemble to fit your needs:\n\n*   `hamcrest/base`:  Defines the types `Matcher`, `Result` and `SelfDescribing`\n    and provides factory functions to create them.  (Unless you want to define\n    your own custom Matchers, you'll only use this indirectly.)\n\n*   `hamcrest/core`:  Defines a set of Matchers for doing basic comparisons,\n    equality testing, nil checking, and grouping/composition matchers.\n\n*   `hamcrest/slices`:  Matchers on slices, such as `EachElem`, `AnyElem`,\n    `ToLen`, `Empty`.\n\n*   `hamcrest/reflect`:  Matchers using type reflection, such as `ToType`,\n    `SameTypeAs`, `SliceOf`, `MapOf`, etc.\n\n*   `hamcrest/strings`:  Matchers for strings.\n\n*   `hamcrest/asserter`:  Defines an `Asserter` that can be used in conjunction \n    with Hamcrest Matchers to produce helpful logging messages at runtime\n    (to stdout, stderr, or any object that implements io.Writer) or in\n    unit tests (using `testing.T` from Go's standard `testing` package).\n\n    Note: the `asserter` package isn't *really* part of Hamcrest:  it's just\n    a handy way of using the Hamcrest results in conjunction with the\n    standard Go testing package.\n\nYou may also choose to write your own Matchers (see *Custom matchers*, below).\n\n\nHow to use hamcrest for testing:\n================================\n\nTo use Hamcrest matchers, create an `Asserter` and use it to\n`Check` or `Assert` that values meet the criteria of those\nmatchers:\n\n\tfunc TestPoint(t *testing.T) {\n\t\tp := Point(3, 4)\n\t\twe := asserter.Using(t)\n\t\twe.AssertThat(p.X, EqualTo(3).Comment(\"x coord\"))\n\t\twe.AssertThat(p.Y, EqualTo(4).Comment(\"y coord\"))\n\t\twe.CheckThat(p, ToString(EqualTo(\"[3, 4]\")))\n\t\twe.CheckThat(p.Magnitude(), EqualTo(5).Comment(\"magnitude\"))\n\t}\n\n(`Assert` methods fail immediately, as `testing.T.FailNow()` does,\nwhile `Check` methods defer failure, as `testing.T.Fail()` does.)\n\nThe `AssertThat` and `CheckThat` functions are designed to create\nconditional checks that read fluently as self-commenting code, and\nare self-describing when failures occur.  For example, the above\ntest might fail with this message:\n\t\n\tFAILURE on input \u0026Point{X:3, Y:4}\n\t\tDid not match ToString(EqualTo([3, 4]))\n\t\tBecause: String() was \"[4, 3]\"\n\t\t\tDid not match EqualTo[[3, 4]]\n\t\t\tBecause: \"[4, 3]\" was not equal to \"[3, 4]\"\n\nOr:\n\tFAILURE on input 5\n\t\tDid not match EqualTo(5)\n\t\tBecause: uint 5 could not be compared to int 5\n\t\tComment: magnitude\n\nNote that the majority of the text descriptions are generated\nautomatically by the matchers.  For typical uses of Hamcrest\nmatchers, the code is largely self-documenting, and the error\nmessages are detailed.\n\nEffort invested in good self-describing matchers can be leveraged\nacross many tests.\n\n\nExamples of using Hamcrest at runtime:\n======================================\n\nJust as in the testing example, create an `Asserter`, but use a factory\nmethod such as `UsingStderr()`, which returns an `Asserter` that logs\nproblems to stderr and calls `panic` on `FailNow`:\n\n\timport (\n\t\t\"github.com/rdrdr/hamcrest/asserter\"\n\t)\n\t\n\tvar we = asserter.UsingStderr()\n\nUse that asserter during init() to make sure globals are properly\ninitialized:\n\n\timport (\n\t\t\"github.com/rdrdr/hamcrest/asserter\"\n\t\t\"github.com/rdrdr/hamcrest/slices\"\n\t\t. \"github.com/rdrdr/hamcrest/core\"\n\t\t\"github.com/rdrdr/hamcrest/strings\"\n\t)\n\tvar we = asserter.UsingStderr()\n\t\n\ttype Server struct {\n\t\thostname string\n\t\tport uint16\n\t}\n\tvar servers = []Server {\n\t\t{ \"news.foo.com\", 8000 },\n\t\t{ \"news.bar.com\", 8888 },\n\t}\n\n\tfunc init() {\n\t\tToHostname := Applying(func(s Server) string {\n\t\t\treturn s.hostname\n\t\t}, \"TransformServerToHostname\")\n\t\tIsInOneOfOurDomains := AnyOf(strings.HasSuffix(\".foo.com\"),\n\t                                 strings.HasSuffix(\".bar.com\"))\n\t\twe.FailNowUnless(servers,\n\t\t\tslices.EachElem(ToHostname(IsInOneOfOurDomains)))\n\t}\n\nOr use the asserter at runtime to guarantee that a method's\npreconditions are met:\n\n\tvar IsValidFilenameForTextFile = AllOf(\n\t\tstrings.HasSuffix(\".txt\").Comment(\"Must have .txt extension.\"),\n\t\tNot(strings.HasPattern(\"[ \\\\t\\\\n\\\\r]\")).Comment(\"whitespace not permitted\"),\n\t\tNot(strings.HasPattern(\"[:////\\\\\\\\]\")).Comment(\"path separators not permitted\"))\n\t\n\tfunc WriteTo(filename string) bool {\n\t\twe.AssertThat(filename, IsValidFilenameForTextFile)\n\t\t// Use filename here.\n\t}\n\nOr use the asserter with `defer` to program by contract, knowing that you\ncan later swap out your typical `Asserter` with an\n`asserter.ThatDoesNothing()` to bypass those checks:\n\n\tIsWellFormedMD5 := AllOf(\n\t\tToLen(EqualTo(32)).Comment(\"MD5 hashes have length 32\"),\n\t\tstrings.HasPattern(\"^([0-9][A-F][a-f])+$\").Comment(\"hex digits\")))\n\t\n\tfunc MD5(data []byte) (result string) {\n\t\twe.AssertNonNil(data)\n\t\tdefer we.AssertThat(result, IsWellFormedMD5)\n\t\t\t\n\t\t// calculate MD5 of data\n\t}\n\n\nOr use it during development to write your tests in the same file as your code:\n\n\tfunc EncodePigLatin(input string) string {\n\t\t...implementation...\n\t}\n\t\n\tfunc init() {\n\t\twe := asserter.UsingStderr()\n\t\tToEncoded := Applying(EncodePigLatin, \"in PigLatin form\")\n\t\twe.AssertThat(\"simple\", ToEncoded(EqualTo(\"imple-say\")))\n\t\twe.AssertThat(\"Capital\"), ToEncoded(EqualTo(\"Apital-Cay\")))\n\t\twe.AssertThat(\"prefix\"), ToEncoded(EqualTo(\"efix-pray\")))\n\t\twe.AssertThat(\"oops\"), ToEncoded(EqualTo(\"oops-ay\")))\n\t\twe.AssertThat(\"your psychotic y!\"),\n\t\t\tToEncoded(EqualTo(\"our-yay ychotic-psay y-ay!\")))\n\t}\n\nAt some future point, this structure will make it easier to cut-and-paste\neach `init()` block into your testing suite.  While moving the block over,\nreplace:\n\n\tfunc init() {\n\t\twe := asserter.UsingStderr()\n\t\t...\n\nWith an `Asserter` that uses the testing infrastructure, instead:\n\n\tfunc Test_EncodePigLatin(t *testing.T) {\n\t\twe := asserter.Using(t)\n\t\t...\n\nA note on library design:\n=========================\n\nHamcrest is designed to be a fluent library.  The Go syntax requires external\nsymbols be preceded by their package name, which can lead to occasionally\nawkward constructions:\n\twe.CheckThat(\"foobar\", core.AllOf(strings.HasPrefix(\"foo\"), strings.HasSuffix(\"bar\")))\n\nTo avoid this clunkiness, Hamcrest matchers are generated by functions that\nyou can assign to local names:\n\tAllOf := core.AllOf\n\tStartsWith := strings.HasPrefix\n\tEndsWith := strings.HasSuffix\n\twe.CheckThat(\"foobar\", AllOf(StartsWith(\"foo\"), EndsWith(\"bar\")))\n\n\nPerformance note:\n=================\nNote:  Hamcrest matchers allocate Description and Result objects to\nexplain in great detail why they did or did not match. However, these\nobjects are lazily evaluated.  Users should be generally aware that\nthere is an *object allocation* cost to using Hamcrest matchers, but\nthere is (generally) no *string construction* cost unless a Hamcrest\nMatcher or Result is explicitly asked to self-describe.\n\nStill, users who are particularly sensitive to performance concerns\nmay wish to think carefully before using Hamcrest matchers in\nperformance-critical bottlenecks.\n\n\nA tour of common matchers\n=========================\n\nHamcrest comes with a library of useful matchers. Here are some of the most\ncommon ones.\n\n  * `Anything` - matches any input.\n  * `True` - only matches bool `true`.\n  * `False` - only matches bool `false`.\n  * `Not(matcher)` - logical not of `matcher`.\n  * `If(m1).Then(m2)` - checks that whenever `m1` matches, so does `m2`.\n  * `IfAndOnlyIf(m1).Then(m2)` - checks that `m1` and `m2` both match/don't match.\n  * `EqualTo(y)` - matches any value `x` where `x == y` is legal and true.\n  * `NotEqualTo(y)` - matches any value `x` where `x != y` is legal and true.\n  * `DeepEqualTo(y)` - matches any value `x` where `reflect.DeepEquals(x, y)` is true.\n  * `GreaterThan(y)` - matches any value `x` where `x \u003e y` is legal and true.\n  * `GreaterThanOrEqualTo(y)` - matches any value `x` where `x \u003c= y` is legal and true.\n  * `LessThan(y)` - matches any value `x` where `x \u003c y` is legal and true.\n  * `LessThanOrEqualTo(y)` - matches any value `x` where `x \u003c= y` is legal and true.\n  * `Nil` - matches values of any type with an `IsNil() bool` method that returns true for the given object.\n  * `NonNil` - matches values of any type with an `IsNil() bool` method that returns false for the given object.\n  * `AnyOf(matchers...)` - short-circuiting n-ary logical Or.\n  * `AllOf(matchers...)` - short-circuiting n-ary logical And.\n\nSyntactic sugar\n===============\n\nHamcrest strives to make your tests as readable as possible. For example,\nthe `Is` matcher is a wrapper that doesn't add any extra behavior to the\nunderlying matcher. The following assertions are equivalent:\n\n    we.AssertThat(x, EqualTo(y));\n    we.AssertThat(x, Is(EqualTo(y)))\n    \nSimilarly, it is possible to simulate common logical conditions using the `logic`\npackage for readability:\n\n  * `Is(matcher)` - equivalent to `matcher`\n  * `Both(matcher1).And(matcher2)` - short-circuiting logical `And`, equivalent to `AllOf(matcher1, matcher2)`\n  * `Either(matcher1).Or(matcher2)` - short-circuiting logical `Or`, equivalent to `AnyOf(matcher1, matcher2)`\n  * `Neither(matcher1).Nor(matcher2)` - short-circuiting logical `Nor`\n  * `If(matcher1).Then(matcher2)` - short-circuiting logical `If/Then`\n  * `Iff(matcher1).Then(matcher2)` - logical `IfAndOnlyIf` (note: iff never short-circuits)\n  * `Either(matcher1).Xor(matcher)` - logical `Xor` (note: xor never short-circuits)\n\n    \nCustom matchers\n===============\n\nExample:\n\n\tfunc IsMultipleOf(k int) *base.Matcher {\n\t\tmatch := func(n int) bool {\n\t\t\treturn n % k == 0\n\t\t}\n\t\treturn base.NewMatcherf(match, \"multiple of %v\", k)\n\t}\n\t\nAnd used:\n\n\twe.CheckThat(recordSize, IsMultipleOf(8).Comment(\n\t\t\"profiling suggests better performance than multiple of 4\"))\n\nOr, if you want more control over the error messages:\n\n\tfunc IsMultipleOf(k int) *base.Matcher {\n\t\tmatch := func(actual interface{}) *base.Result {\n\t\t\tif n, ok := actual.(int); ok {\n\t\t\t\tif remainder := n % k; remainder != 0 {\n\t\t\t\t\treturn base.NewResultf(false,\n\t\t\t\t\t\t\"was not a multiple of %v (remainder %v)\", k, remainder)\n\t\t\t\t}\n\t\t\t\treturn base.NewResultf(true, \"was a multiple of %v\", k)\n\t\t\t}\n\t\t\treturn base.NewResultf(false, \"was a %T, expected an int!\", actual)\n\t\t}\n\t\treturn base.NewMatcherf(match, \"multiple of %v\", k)\n\t}\n\n\n\n","funding_links":[],"categories":["Testing","测试","測試","\u003cspan id=\"测试-testing\"\u003e测试 Testing\u003c/span\u003e","Testing Frameworks","测试相关","测试相关`测试库和测试数据集生成库`","Template Engines"],"sub_categories":["Testing Frameworks","HTTP Clients","HTTP客户端","高級控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","Advanced Console UIs","Middlewares","查询语","交流","高级控制台界面"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frdrdr%2Fhamcrest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frdrdr%2Fhamcrest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frdrdr%2Fhamcrest/lists"}