{"id":20606133,"url":"https://github.com/rudymatela/leancheck","last_synced_at":"2025-08-20T08:32:35.933Z","repository":{"id":33979237,"uuid":"37725938","full_name":"rudymatela/leancheck","owner":"rudymatela","description":"enumerative property-based testing for Haskell","archived":false,"fork":false,"pushed_at":"2024-02-09T10:39:14.000Z","size":1344,"stargazers_count":51,"open_issues_count":3,"forks_count":7,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-04-29T18:09:03.258Z","etag":null,"topics":["enumerative-testing","haskell","leancheck","property-based-testing","property-testing","testing","testing-tools"],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/leancheck","language":"Haskell","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/rudymatela.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","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":"2015-06-19T14:22:02.000Z","updated_at":"2024-06-21T16:52:41.751Z","dependencies_parsed_at":"2024-01-23T18:28:52.088Z","dependency_job_id":"f2a9c316-2860-445e-aa2a-236e2f2497e2","html_url":"https://github.com/rudymatela/leancheck","commit_stats":{"total_commits":1146,"total_committers":6,"mean_commits":191.0,"dds":0.005235602094240788,"last_synced_commit":"6e14eafbd866ed01840470a3415eefcdad2eebc6"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fleancheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fleancheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fleancheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fleancheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rudymatela","download_url":"https://codeload.github.com/rudymatela/leancheck/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230049056,"owners_count":18164832,"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":["enumerative-testing","haskell","leancheck","property-based-testing","property-testing","testing","testing-tools"],"created_at":"2024-11-16T09:32:39.552Z","updated_at":"2024-12-19T09:07:25.294Z","avatar_url":"https://github.com/rudymatela.png","language":"Haskell","readme":"LeanCheck\n=========\n\n[![LeanCheck's Build Status][build-status]][build-log]\n[![LeanCheck on Hackage][hackage-version]][leancheck-on-hackage]\n[![LeanCheck on Stackage LTS][stackage-lts-badge]][leancheck-on-stackage-lts]\n[![LeanCheck on Stackage Nightly][stackage-nightly-badge]][leancheck-on-stackage-nightly]\n\n![LeanCheck logo][leancheck-logo]\n\nLeanCheck is a simple enumerative [property-based testing] library.  Properties\nare defined as Haskell functions returning a boolean value which should be\n`True` for all possible choices of argument values.    LeanCheck applies\nenumerated argument values to these properties in search for a counterexample.\nProperties can be viewed as parameterized unit tests.\n\nLeanCheck works by producing *tiers* of test values: a possibly infinite list\nof finite sublists of same-and-increasingly-sized values.  This enumeration is\nsimilar to [Feat]'s.  However, the ranking and ordering of values are defined\ndifferently.  The interface is also different.\n\nThroughout this README lines that begin with the [symbol `\u003e`] indicate a line\nentered into an interactive interpreter (`ghci`).  The result of evaluating the\nexpression is then printed on the following line.\n\nLeanCheck implementation is easy to understand.\n[LeanCheck's core] is under 200 lines of code.\n\n\nInstalling\n----------\n\nTo install the [latest LeanCheck version from Hackage] just run:\n\n\t$ cabal update\n\t$ cabal install leancheck\n\nStarting from Cabal v3.0, you need to pass `--lib` as an argument to\n`cabal install` to install packages globally on the `default` user environment:\n\n\t$ cabal install leancheck --lib\n\nIf you already have LeanCheck installed\n[Cabal may refuse to update](https://github.com/haskell/cabal/issues/7373)\nto the latest version.\nTo update, you need to reset your user's cabal installation with:\n\n\trm -rf ~/.cabal/{bin,lib,logs,share,store} ~/.ghc/*/\n\nWARNING: the above command will erase all user-local packages.\n\nLeanCheck has (official) packages available on\n[Stackage](https://www.stackage.org/package/leancheck),\n[OpenSUSE](https://packagehub.suse.com/packages/ghc-leancheck/),\n[Gentoo](https://packages.gentoo.org/packages/dev-haskell/leancheck),\n[Arch Linux](https://archlinux.org/packages/community/x86_64/haskell-leancheck/) and\n[NixOS](https://hydra.nixos.org/job/nixpkgs/trunk/haskellPackages.leancheck.x86_64-linux).\n\n\n\nChecking if properties are True\n-------------------------------\n\nTo check if properties are True,\njust use the function [`holds`] `:: Testable a =\u003e Int -\u003e a -\u003e Bool`.\nIt takes _two arguments_:\nthe _number of values_ to test\nand a _property_ (function returning Bool),\nthen, it returns a boolean indicating whether the property holds.\nSee (ghci):\n\n\t\u003e import Test.LeanCheck\n\t\u003e import Data.List\n\t\u003e holds 100 $ \\xs -\u003e sort (sort xs) == sort (xs::[Int])\n\tTrue\n\t\u003e holds 100 $ \\xs -\u003e [] `union` xs == (xs::[Int])\n\tFalse\n\nAs a rule-of-thumb, you should run holds for 500, 1 000, or 10 000 tests.\nWith more than that you may run out-of-memory depending on the types being\ntested.\n\n\nFinding counter examples\n------------------------\n\nTo find counter examples to properties,\nyou can use the function [`counterExample`] `:: Testable a =\u003e Int -\u003e a -\u003e Maybe [String]`.\nIt takes _two arguments_:\nthe _number of values_ to test\nand a _property_ (function returning Bool).\nThen, it returns Nothing if no results are found or Just a list of Strings\nrepresenting the offending arguments to the property.\nSee (ghci):\n\n\t\u003e import Test.LeanCheck\n\t\u003e import Data.List\n\n\t\u003e counterExample 100 $ \\xs -\u003e sort (sort xs) == sort (xs::[Int])\n\tNothing\n\n\t\u003e counterExample 100 $ \\xs -\u003e [] `union` xs == (xs::[Int])\n\tJust [\"[0,0]\"]\n\n\t\u003e counterExample 100 $ \\xs ys -\u003e xs `union` ys == ys `union` (xs::[Int])\n\tJust [\"[]\",\"[0,0]\"]\n\n\nChecking properties like in SmallCheck/QuickCheck\n-------------------------------------------------\n\nTo \"check\" properties like in [SmallCheck] and [QuickCheck]\nautomatically printing results on standard output,\nyou can use the function [`check`] `:: Testable a =\u003e a -\u003e IO ()`.\n\n\t\u003e import Test.LeanCheck\n\t\u003e import Data.List\n\n\t\u003e check $ \\xs -\u003e sort (sort xs) == sort (xs::[Int])\n\t+++ OK, passed 200 tests.\n\n\t\u003e check $ \\xs ys -\u003e xs `union` ys == ys `union` (xs::[Int])\n\t*** Failed! Falsifiable (after 4 tests):\n\t[] [0,0]\n\nThe function [`check`] tests for a maximum of 200 tests.\nTo check for a maximum of `n` tests, use [`checkFor`] `n`.\nTo get a boolean result wrapped in `IO`, use [`checkResult`] or [`checkResultFor`].\nThere is no \"quiet\" option, just use [`holds`] or [`counterExample`] in that case.\n\n\nTesting user-defined types\n--------------------------\n\nLeanCheck works on properties with [`Listable`] argument types.\n[`Listable`] instances are declared similarly to SmallCheck:\n\n\tdata MyType = MyConsA\n\t            | MyConsB Int\n\t            | MyConsC Int Char\n\t            | MyConsD String\n\n\tinstance Listable MyType where\n\t  tiers = cons0 MyConsA\n\t       \\/ cons1 MyConsB\n\t       \\/ cons2 MyConsC\n\t       \\/ cons1 MyConsD\n\nFor types that do not have a constraning data invariant, instances can be\nautomatically derived with [Template Haskell] by using [`deriveListable`] like\nso:\n\n\tderiveListable ''MyType\n\nThe [`tiers`] function return a potentially infinite list of finite sub-lists\n(tiers).  Each successive tier has values of increasing size.\n\n\ttiers :: Listable a =\u003e [[a]]\n\nFor convenience, the function [`list`] returns a potentially infinite list\nof values of the bound type:\n\n\tlist :: Listable a =\u003e [a]\n\nSo, for example:\n\n\t\u003e take 5 (list :: [(Int,Int)])\n\t[(0,0),(0,1),(1,0),(0,-1),(1,1)]\n\nThe `list` function can be used to debug your custom instances.\n\n[`Listable`] class instances are more customizable than what is described here:\ncheck source comments or haddock documentation for details.\n\n\nStandard Listable Instances\n---------------------------\n\nLeanCheck comes out-of-the-box with [`Listable`] instances for all types in the\n[Haskell 2010 Language Report] with [the intentional exception of a few types].\nThe [leancheck-instances] package aims to support types in the\n[Haskell Platform] -- `$ cabal install leancheck-instances`.\n\n\nProviders for Tasty, test-framework and Hspec\n---------------------------------------------\n\nThe following providers allow including LeanCheck properties into\n[Tasty], [test-framework] or [Hspec] test suites.\n\n* [LeanCheck provider for Tasty]\n  -- `$ cabal install tasty-leancheck` ;\n* [LeanCheck provider for test-framework]\n  -- `$ cabal install test-framework-leancheck` ;\n* [LeanCheck provider for Hspec]\n  -- `$ cabal install hspec-leancheck` .\n\n\nMemory usage\n------------\n\nDue to the way it is implemented (using lists of lists), LeanCheck can be quite\nmemory intensive if we set the maximum number of tests of a property to\nmillions of values (YMMV).\n\nFor the default maximum number of tests (200) you should be safe on most cases.\nIf you use 1 000 or 10 000 as the maximum number of tests for a property you're\nalso generally safe.  More than that, it is in a hit or miss basis.\n\nFor more details, see [LeanCheck memory usage].\n\n\nBeginner friendliness\n---------------------\n\nLeanCheck strives to be beginner/student friendly both in the interface and its\nimplementation.  For instance, to understand [LeanCheck's core], one does not\nneed to understand Monads as they aren't used at all there.\n\nIn the name of keeping the implementation easy to understand,\na compromise were made in terms of performance\n(cf. [LeanCheck memory usage]).\n\nLeanCheck is mostly [Haskell 98] compliant and almost [Haskell 2010] compliant.\nWith the exception of [`Listable`] derivation modules ([TH] and [Generics]),\nthe only extension used by LeanCheck is [CPP].  This is to maintain\ncompatibility with different compilers.  LeanCheck even compiles and runs on\n[Hugs98] from September 2006.\n\nLeanCheck has 100% Haddock coverage with most functions having examples.\n\n\nFurther reading\n---------------\n\nFor a detailed documentation of each function, see\n[LeanCheck's Haddock documentation].\n\nFor an introduction to property-based testing\nand a step-by-step guide to LeanCheck, see the\n[tutorial on property-based testing with LeanCheck]\n\\(`doc/tutorial.md` in the source repository).\n\nLeanCheck is subject to a chapter in a [PhD Thesis (2017)].\n\nLeanCheck has a list of [frequently asked questions] and answers.\n\n[LeanCheck's Haddock documentation]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html\n[tutorial on property-based testing with LeanCheck]: https://github.com/rudymatela/leancheck/blob/master/doc/tutorial.md\n[LeanCheck memory usage]: https://github.com/rudymatela/leancheck/blob/master/doc/memory-usage.md\n[frequently asked questions]: https://github.com/rudymatela/leancheck/blob/master/doc/faq.md\n[latest LeanCheck version from Hackage]: https://hackage.haskell.org/package/leancheck\n\n[`Listable`]:       https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#t:Listable\n[`holds`]:          https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:holds\n[`counterExample`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:counterExample\n[`check`]:          https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:check\n[`checkFor`]:       https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:checkFor\n[`checkResult`]:    https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:checkResult\n[`checkResultFor`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:checkResultFor\n[`tiers`]:          https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:tiers\n[`list`]:           https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:list\n[`deriveListable`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:deriveListable\n[LeanCheck's core]: https://github.com/rudymatela/leancheck/blob/master/src/Test/LeanCheck/Core.hs\n\n[property-based testing]: https://github.com/rudymatela/leancheck/blob/master/doc/tutorial.md\n[Feat]: https://hackage.haskell.org/package/testing-feat\n[SmallCheck]: https://hackage.haskell.org/package/smallcheck\n[QuickCheck]: https://hackage.haskell.org/package/QuickCheck\n[PhD Thesis (2017)]: https://matela.com.br/thesis-rudy.pdf\n\n[symbol `\u003e`]: https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810780208\n[Template Haskell]: https://wiki.haskell.org/Template_Haskell\n\n[Tasty]:          https://github.com/feuerbach/tasty#readme\n[test-framework]: https://haskell.github.io/test-framework/\n[Hspec]:          https://hspec.github.io/\n[LeanCheck provider for Tasty]:          https://hackage.haskell.org/package/tasty-leancheck\n[LeanCheck provider for test-framework]: https://hackage.haskell.org/package/test-framework-leancheck\n[LeanCheck provider for Hspec]:          https://hackage.haskell.org/package/hspec-leancheck\n[leancheck-instances]:                   https://hackage.haskell.org/package/leancheck-instances\n[the intentional exception of a few types]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck-Basic.html\n[Haskell 2010 Language Report]:          https://www.haskell.org/onlinereport/haskell2010/\n[Haskell 2010]:                          https://www.haskell.org/onlinereport/haskell2010/\n[Haskell 98]:                            https://www.haskell.org/onlinereport/\n[Haskell Platform]:                      https://www.haskell.org/platform/\n[Hugs98]:                                https://www.haskell.org/hugs/\n[TH]:  https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell\n[CPP]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/phases.html#extension-CPP\n[Generics]: https://hackage.haskell.org/package/base/docs/GHC-Generics.html\n\n[leancheck-logo]: https://github.com/rudymatela/leancheck/raw/master/doc/leancheck.svg?sanitize=true\n\n[build-log]:    https://github.com/rudymatela/leancheck/actions/workflows/build.yml\n[build-status]: https://github.com/rudymatela/leancheck/actions/workflows/build.yml/badge.svg\n[hackage-version]: https://img.shields.io/hackage/v/leancheck.svg\n[leancheck-on-hackage]: https://hackage.haskell.org/package/leancheck\n[stackage-lts-badge]:            https://stackage.org/package/leancheck/badge/lts\n[stackage-nightly-badge]:        https://stackage.org/package/leancheck/badge/nightly\n[leancheck-on-stackage]:         https://stackage.org/package/leancheck\n[leancheck-on-stackage-lts]:     https://stackage.org/lts/package/leancheck\n[leancheck-on-stackage-nightly]: https://stackage.org/nightly/package/leancheck\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Fleancheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frudymatela%2Fleancheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Fleancheck/lists"}