{"id":20606129,"url":"https://github.com/rudymatela/fitspec","last_synced_at":"2025-10-08T01:36:56.619Z","repository":{"id":33979335,"uuid":"37726036","full_name":"rudymatela/fitspec","owner":"rudymatela","description":"refine properties for testing Haskell programs","archived":false,"fork":false,"pushed_at":"2025-01-30T17:07:40.000Z","size":651,"stargazers_count":75,"open_issues_count":0,"forks_count":0,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-10-05T11:25:32.682Z","etag":null,"topics":["enumerative-testing","leancheck","mutation-testing","property-based-testing","property-refinement","property-testing"],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/fitspec","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"utom/sketch-measure","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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-06-19T14:23:38.000Z","updated_at":"2025-09-25T15:48:03.000Z","dependencies_parsed_at":"2024-11-16T09:32:46.844Z","dependency_job_id":"5ae76955-5007-4bad-9d51-e479f8536386","html_url":"https://github.com/rudymatela/fitspec","commit_stats":{"total_commits":769,"total_committers":2,"mean_commits":384.5,"dds":"0.011703511053316018","last_synced_commit":"a2fc0ee602bf6b6dcf37039900c2ee5d9eb0126d"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/rudymatela/fitspec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Ffitspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Ffitspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Ffitspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Ffitspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rudymatela","download_url":"https://codeload.github.com/rudymatela/fitspec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudymatela%2Ffitspec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278877097,"owners_count":26061380,"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","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"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":["enumerative-testing","leancheck","mutation-testing","property-based-testing","property-refinement","property-testing"],"created_at":"2024-11-16T09:32:38.920Z","updated_at":"2025-10-08T01:36:56.603Z","avatar_url":"https://github.com/rudymatela.png","language":"Haskell","readme":"FitSpec\n=======\n\n[![FitSpec Build Status][build-status]][build-log]\n[![FitSpec on Hackage][hackage-version]][fitspec-on-hackage]\n[![FitSpec on Stackage LTS][stackage-lts-badge]][fitspec-on-stackage-lts]\n[![FitSpec on Stackage Nightly][stackage-nightly-badge]][fitspec-on-stackage-nightly]\n\n![FitSpec logo][fitspec-logo]\n\nFitSpec provides automated assistance in the task of refining test properties\nfor [Haskell] functions.  FitSpec tests mutant variations of functions under\ntest against a given property set, recording any surviving mutants that pass\nall tests.  FitSpec then reports:\n\n* *surviving mutants:*\n  indicating incompleteness of properties,\n  prompting the user to amend a property or to add a new one;\n* *conjectures:*\n  indicating redundancy in the property set,\n  prompting the user to remove properties so to reduce the cost of testing.\n\nInstalling FitSpec\n------------------\n\nTo install the [latest FitSpec version from Hackage], just:\n\n    $ cabal install fitspec\n\nPre-requisites are [cmdargs] and [leancheck].\nThey should be automatically resolved and installed by [Cabal].\n\nStarting from Cabal v3.0, you need to pass `--lib` as an argument to\n`cabal install`:\n\n\t$ cabal install fitspec --lib\n\n\nUsing FitSpec\n-------------\n\nAs an example, consider the following properties describing a `sort` function:\n\n    prop_ordered xs = ordered (sort xs)\n    prop_length xs = length (sort xs) == length xs\n    prop_elem x xs = elem x (sort xs) == elem x xs\n    prop_notElem x xs = notElem x (sort xs) == notElem x xs\n    prop_min x xs = head (sort (x:xs)) == minimum (x:xs)\n\nWe provide the above properties to FitSpec in the following program:\n\n    import Test.FitSpec\n    import Data.List\n\n    properties sort =\n      [ property $ \\xs -\u003e ordered (sort xs)\n      , property $ \\xs -\u003e length (sort xs) == length xs\n      , property $ \\x xs -\u003e elem x (sort xs) == elem x xs\n      , property $ \\x xs -\u003e notElem x (sort xs) == notElem x xs\n      , property $ \\x xs -\u003e head (sort (x:xs)) == minimum (x:xs)\n      ]\n      where\n      ordered (x:y:xs) = x \u003c= y \u0026\u0026 ordered (y:xs)\n      ordered _        = True\n\n    main = mainWith args { names = [\"sort xs\"]\n                         , nMutants = 4000\n                         , nTests = 4000\n                         , timeout = 0\n                         }\n                    (sort::[Word2]-\u003e[Word2])\n                    properties\n\nThe above program reports, after a few seconds, that our property set is\napparently *neither minimal nor complete*.\n\n    $ ./fitspec-sort\n    Apparent incomplete and non-minimal specification based on\n    4000 test cases for each of properties 1, 2, 3, 4 and 5\n    for each of 4000 mutant variations.\n\n    3 survivors (99% killed), smallest:\n      \\xs -\u003e case xs of\n               [0,0,1] -\u003e [0,1,1]\n               _ -\u003e sort xs\n\n    apparent minimal property subsets:  {1,2,3} {1,2,4}\n    conjectures:  {3}    =  {4}     96% killed (weak)\n                  {1,3} ==\u003e {5}     98% killed (weak)\n\n*Completeness:* Of 4000 mutants, 3 survive testing against our 5 properties.\nThe surviving mutant is clearly not a valid implementation of `sort`, but\nindeed satisfies those properties.  As a specification, the property set is\n*incomplete* as it omits to require that sorting preserves the number of\noccurrences of each element value: `\\x xs -\u003e count x (sort xs) == count x xs`\n\n*Minimality:*\nSo far as testing has revealed, properties 3 and 4 are equivalent and property\n5 follows from 1 and 3 (conjectures).  It is *up to the user* to check whether\nthese conjectures are true.  Indeed they are, so in future testing we could\nsafely omit properties 4 and 5.\n\n*Refinement:* If we omit redundant properties, and add a property to kill the\nsurviving mutant, our refined properties are:\n\n    properties sort =\n      [ \\xs -\u003e   ordered (sort xs)\n      , \\xs -\u003e    length (sort xs) == length xs\n      , \\x xs -\u003e  elem x (sort xs) == elem x xs\n      , \\x xs -\u003e count x (sort xs) == count x xs\n      ]\n\n(The implementation of `count` is left as an exercise to the reader.)\n\nFitSpec now reports:\n\n    Apparent complete but non-minimal specification based on\n    4000 test cases for each of properties 1, 2, 3 and 4\n    for each of 4000 mutant variations.\n\n    0 survivors (100% killed).\n\n    apparent minimal property subsets:  {1,4}\n    conjectures:  {4} ==\u003e {2,3}     99% killed (weak)\n\nAs reported, properties 2 and 3 are implied by property 4, since that is true,\nwe can safely remove properties 2 and 3 to arrive at a minimal and complete\npropety set.\n\n\n### User-defined datatypes\n\nIf you want to use FitSpec to analyse functions over user-defined datatypes,\nthose datatypes should be made instances of the [Listable], [Mutable] and\n[ShowMutable] typeclasses.  Check the Haddock documentation of each class for\nhow to define instances manually.  If datatypes do not follow a data invariant,\ninstances can be automatically derived using [TH] by:\n\n    deriveMutable ''DataType\n\n\nMore documentation\n------------------\n\nFor more examples, see the [eg](eg) and [bench](bench) folders.\n\nFor further documentation, consult the [doc](doc) folder and [FitSpec API]\ndocumentation on Hackage.\n\nFitSpec has been subject to a paper, see the\n[FitSpec paper on Haskell Symposium 2016](https://matela.com.br/fitspec.pdf).\nFitSpec is also subject to a chapter in a [PhD Thesis (2017)].\n\n[Listable]:    https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#t:Listable\n[Mutable]:     https://hackage.haskell.org/package/fitspec/docs/Test-FitSpec.html#t:Mutable\n[ShowMutable]: https://hackage.haskell.org/package/fitspec/docs/Test-FitSpec.html#t:ShowMutable\n[FitSpec API]: https://hackage.haskell.org/package/fitspec/docs/Test-FitSpec.html\n\n[leancheck]: https://hackage.haskell.org/package/leancheck\n[cmdargs]:   https://hackage.haskell.org/package/cmdargs\n[pretty]:    https://hackage.haskell.org/package/pretty\n\n[TH]:      https://wiki.haskell.org/Template_Haskell\n[Cabal]:   https://www.haskell.org/cabal\n[Haskell]: https://www.haskell.org/\n[PhD Thesis (2017)]: https://matela.com.br/thesis-rudy.pdf\n\n[fitspec-logo]: https://github.com/rudymatela/fitspec/raw/master/doc/fitspec.svg?sanitize=true\n\n[build-log]:    https://github.com/rudymatela/fitspec/actions/workflows/build.yml\n[build-status]: https://github.com/rudymatela/fitspec/actions/workflows/build.yml/badge.svg\n[hackage-version]: https://img.shields.io/hackage/v/fitspec.svg\n[fitspec-on-hackage]:                  https://hackage.haskell.org/package/fitspec\n[latest FitSpec version from Hackage]: https://hackage.haskell.org/package/fitspec\n[stackage-lts-badge]:          https://stackage.org/package/fitspec/badge/lts\n[stackage-nightly-badge]:      https://stackage.org/package/fitspec/badge/nightly\n[fitspec-on-stackage]:         https://stackage.org/package/fitspec\n[fitspec-on-stackage-lts]:     https://stackage.org/lts/package/fitspec\n[fitspec-on-stackage-nightly]: https://stackage.org/nightly/package/fitspec\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Ffitspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frudymatela%2Ffitspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudymatela%2Ffitspec/lists"}