{"id":20606124,"url":"https://github.com/rudymatela/extrapolate","last_synced_at":"2025-04-15T02:42:41.639Z","repository":{"id":62435940,"uuid":"99000880","full_name":"rudymatela/extrapolate","owner":"rudymatela","description":"generalize counter-examples of property-based testing","archived":false,"fork":false,"pushed_at":"2024-02-09T09:53:57.000Z","size":534,"stargazers_count":13,"open_issues_count":2,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-25T22:21:41.000Z","etag":null,"topics":["counter-example-generalization","debugging","enumerative-testing","generalization","haskell","leancheck","property-based-testing","property-testing","testing","testing-tools"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rudymatela.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}},"created_at":"2017-08-01T12:50:40.000Z","updated_at":"2021-12-03T16:25:24.000Z","dependencies_parsed_at":"2024-02-09T10:25:32.327Z","dependency_job_id":"ea94acc8-6b2f-4802-b0b1-62b010bbc65c","html_url":"https://github.com/rudymatela/extrapolate","commit_stats":{"total_commits":645,"total_committers":1,"mean_commits":645.0,"dds":0.0,"last_synced_commit":"f72fa413bbc30bb425b27cb5b9099d6ba0435268"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fextrapolate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fextrapolate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fextrapolate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Fextrapolate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rudymatela","download_url":"https://codeload.github.com/rudymatela/extrapolate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248997049,"owners_count":21195785,"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":["counter-example-generalization","debugging","enumerative-testing","generalization","haskell","leancheck","property-based-testing","property-testing","testing","testing-tools"],"created_at":"2024-11-16T09:32:38.216Z","updated_at":"2025-04-15T02:42:41.604Z","avatar_url":"https://github.com/rudymatela.png","language":"Haskell","readme":"Extrapolate\n===========\n\n[![Extrapolate Build Status][build-status]][build-log]\n[![Extrapolate on Hackage][hackage-version]][extrapolate-on-hackage]\n[![Extrapolate on Stackage LTS][stackage-lts-badge]][extrapolate-on-stackage-lts]\n[![Extrapolate on Stackage Nightly][stackage-nightly-badge]][extrapolate-on-stackage-nightly]\n\n![Extrapolate logo][extrapolate-logo]\n\nExtrapolate is a [property-based testing] library for [Haskell]\ncapable of reporting generalized counter-examples.\n\n\nInstalling Extrapolate\n----------------------\n\nTo install the latest version of [Extrapolate from Hackage] using [cabal], just:\n\n\t$ cabal update\n\t$ cabal install extrapolate\n\nTo test if it installed correctly, follow through the next section.\n\nStarting from Cabal v3, you need to pass `--lib` to `cabal install`:\n\n\t$ cabal install extrapolate --lib\n\n\nUsing Extrapolate\n-----------------\n\nTo use Extrapolate, you first import the [`Test.Extrapolate`] module,\nthen pass any properties you with to test to the function [`check`]:\n\n\t$ ghci\n\t\u003e import Test.Extrapolate\n\t\u003e check $ \\x y -\u003e x + y == y + (x :: Int)\n\t+++ OK, passed 360 tests.\n\n\t\u003e import Data.List (nub)\n\t\u003e check $ \\xs -\u003e nub xs == (xs :: [Int])\n\t*** Failed! Falsifiable (after 3 tests):\n\t[0,0]\n\n\tGeneralization:\n\tx:x:_\n\nThe operator [`+`] is commutative.  The function [`nub`] is not an identity.\n\n\n### Configuring the number of tests\n\nTo increase the number of tests, use the [`for`] combinator:\n\n\t$ ghci\n\t\u003e import Test.Extrapolate\n\t\u003e check `for` 1000 $ \\x y -\u003e x + y == y + (x :: Int)\n\t+++ OK, passed 1000 tests.\n\n\n### Customizing the background functions (allowed in side-conditions)\n\nTo customize the background functions, use the [`withBackground`] combinator:\n\n\t$ ghci\n\t\u003e import Test.Extrapolate\n\t\u003e import Data.List (nub)\n\t\u003e let hasDups xs  =  nub xs /= (xs :: [Int])\n\t\u003e check `withBackground` [constant \"hasDups\" hasDups] $ \\xs -\u003e nub xs == (xs :: [Int])\n\t*** Failed! Falsifiable (after 3 tests):\n\t[0,0]\n\n\tGeneralization:\n\tx:x:_\n\n\tConditional Generalization:\n\txs  when  hasDups xs\n\nPerhaps the example above is silly (`hasDups` is the negation of the property\nitself!), but it illustrates the use of [`withBackground`].\n\n\nThe combinators [`for`] and [`withBackground`] can be used in conjunction:\n\n\t\u003e check `for` 100 `withBackground` [...] $ property\n\nDon't forget the dollar sign [`$`].\n\n\nAnother Example\n---------------\n\nConsider the following (faulty) sort function and a property about it:\n\n    sort :: Ord a =\u003e [a] -\u003e [a]\n    sort []      =  []\n    sort (x:xs)  =  sort (filter (\u003c x) xs)\n                 ++ [x]\n                 ++ sort (filter (\u003e x) xs)\n\n    prop_sortCount :: Ord a =\u003e a -\u003e [a] -\u003e Bool\n    prop_sortCount x xs  =  count x (sort xs) == count x xs\n      where\n      count x = length . filter (== x)\n\nAfter testing the property, Extrapolate returns a fully defined counter-example\nalong with a generalization:\n\n    \u003e import Test.Extrapolate\n    \u003e check (prop_sortCount :: Int -\u003e [Int] -\u003e Bool)\n    *** Failed! Falsifiable (after 4 tests):\n    0 [0,0]\n\n    Generalization:\n    x (x:x:_)\n\nThis hopefully makes it easier to find the source of the bug.  In this case,\nthe faulty sort function discards repeated elements.\n\n\nFurther reading\n---------------\n\nFor more examples, see the [eg](eg) folder.\nFor type signatures, other options and uses,\nsee [Extrapolate's API documentation].\n\nThere are two other tools for [Haskell] capable of producing generalized\ncounter-examples: [SmartCheck] and [Lazy SmallCheck 2012].\n\nExtrapolate was presented at [IFL 2017] and was subject to a paper titled\n[Extrapolate: generalizing counterexamples of functional test properties](https://matela.com.br/extrapolate.pdf).\nExtrapolate is also subject to a chapter in a [PhD Thesis (2017)].\n\n[extrapolate-on-hackage]:          https://hackage.haskell.org/package/extrapolate\n[Extrapolate from Hackage]:        https://hackage.haskell.org/package/extrapolate\n[Extrapolate's API documentation]: https://hackage.haskell.org/package/extrapolate/docs/Test-Extrapolate.html\n[`Test.Extrapolate`]:              https://hackage.haskell.org/package/extrapolate/docs/Test-Extrapolate.html\n[`check`]:                         https://hackage.haskell.org/package/extrapolate/docs/Test-Extrapolate.html#v:check\n[`for`]:                           https://hackage.haskell.org/package/extrapolate/docs/Test-Extrapolate.html#v:for\n[`withBackground`]:                https://hackage.haskell.org/package/extrapolate/docs/Test-Extrapolate.html#v:withBackground\n[`$`]:                             https://hackage.haskell.org/package/base-4.10.0.0/docs/Prelude.html#v:-36-\n[`+`]:                             https://hackage.haskell.org/package/base/docs/Prelude.html#v:-43-\n[`nub`]:                           https://hackage.haskell.org/package/base/docs/Data-List.html#v:nub\n[Haskell]:                         https://www.haskell.org/\n[cabal]:                           https://www.haskell.org/cabal/\n[property-based testing]:          https://github.com/rudymatela/leancheck/blob/master/doc/tutorial.md\n\n[IFL 2017]:             http://iflconference.org/\n[SmartCheck]:           https://github.com/leepike/SmartCheck\n[Lazy SmallCheck 2012]: https://github.com/UoYCS-plasma/lazysmallcheck2012\n[PhD Thesis (2017)]: https://matela.com.br/thesis-rudy.pdf\n\n[extrapolate-logo]: https://github.com/rudymatela/extrapolate/raw/master/doc/extrapolate.svg?sanitize=true\n\n[build-log]:    https://github.com/rudymatela/extrapolate/actions/workflows/build.yml\n[build-status]: https://github.com/rudymatela/extrapolate/actions/workflows/build.yml/badge.svg\n[hackage-version]: https://img.shields.io/hackage/v/extrapolate.svg\n[stackage-lts-badge]:              https://stackage.org/package/extrapolate/badge/lts\n[stackage-nightly-badge]:          https://stackage.org/package/extrapolate/badge/nightly\n[extrapolate-on-stackage]:         https://stackage.org/package/extrapolate\n[extrapolate-on-stackage-lts]:     https://stackage.org/lts/package/extrapolate\n[extrapolate-on-stackage-nightly]: https://stackage.org/nightly/package/extrapolate\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Fextrapolate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frudymatela%2Fextrapolate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Fextrapolate/lists"}