{"id":33191316,"url":"https://github.com/cmeeren/Faqt","last_synced_at":"2025-11-21T00:02:05.052Z","repository":{"id":181064848,"uuid":"666161276","full_name":"cmeeren/Faqt","owner":"cmeeren","description":"Fluent assertions for F#","archived":false,"fork":false,"pushed_at":"2025-09-18T07:02:01.000Z","size":764,"stargazers_count":73,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-23T10:53:29.199Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmeeren.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2023-07-13T21:24:18.000Z","updated_at":"2025-10-22T17:09:10.000Z","dependencies_parsed_at":"2023-09-23T09:58:30.674Z","dependency_job_id":"5c8b13fe-277b-4e64-b78c-dc44ec572e1e","html_url":"https://github.com/cmeeren/Faqt","commit_stats":{"total_commits":692,"total_committers":4,"mean_commits":173.0,"dds":"0.45375722543352603","last_synced_commit":"bb3a9852515b4f483b421c0d767cbf28686c4f99"},"previous_names":["cmeeren/faqt"],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/cmeeren/Faqt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmeeren%2FFaqt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmeeren%2FFaqt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmeeren%2FFaqt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmeeren%2FFaqt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmeeren","download_url":"https://codeload.github.com/cmeeren/Faqt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmeeren%2FFaqt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285532343,"owners_count":27187706,"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-11-20T02:00:05.334Z","response_time":54,"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":[],"created_at":"2025-11-16T06:00:41.329Z","updated_at":"2025-11-21T00:02:05.047Z","avatar_url":"https://github.com/cmeeren.png","language":"F#","funding_links":[],"categories":["Testing"],"sub_categories":["Performance Analysis"],"readme":"Faqt\n====\n\n**Fantastic fluent assertions for your F# tests and domain code.**\n\n\u003cimg src=\"https://raw.githubusercontent.com/cmeeren/Faqt/main/logo/faqt-logo-docs.png\" width=\"300\" align=\"right\" /\u003e\n\nFaqt improves on the best of [FluentAssertions](https://github.com/fluentassertions/fluentassertions)\nand [Shouldly](https://github.com/shouldly/shouldly) and serves it steaming hot on a silver platter to the discerning F#\ndeveloper.\n\n**It aims to be the best assertion library for F#.**\n\nIf you don't agree, I consider that a bug - please raise an issue. 😉\n\n### Versioning and breaking changes\n\nFaqt follows [SemVer v2.0.0](https://semver.org/) and aims to preserve **source and binary** compatibility between\nreleases, except when the major version is incremented. Note that any change to the assertion message format is\nconsidered a non-breaking change.\n\n## Table of contents\n\n\u003c!-- TOC --\u003e\n\n* [A motivating example](#a-motivating-example)\n* [Installation and requirements](#installation-and-requirements)\n* [Faqt in a nutshell](#faqt-in-a-nutshell)\n* [Documentation](#documentation)\n* [Contributing](#contributing)\n\n\u003c!-- TOC --\u003e\n\n## A motivating example\n\nHere is an example of what you can do with Faqt. Simply use `Should()` to start asserting. For subsequent calls to\n`Should` in the same chain, use `Should(())` (double parentheses - this is required for subject names to work properly).\nLike FluentAssertions, all assertions support an optional \"because\" parameter that will be used in the output.\n\n```f#\n// Example type definition for clarity\ntype Customer =\n    | Internal of {| ContactInfo: {| Name: {| LastName: string |} |} option |}\n    | External of {| Id: int |}\n\nopen Faqt\n\n// Assertions in test or domain code\ncustomer\n    .Should()\n    .BeOfCase(Internal, \"This function should only be called with internal customers\")\n    .Whose.ContactInfo.Should(())\n    .BeSome()\n    .Whose.Name.LastName.Should(())\n    .Be(\"Armstrong\", \"Only customers named Armstrong get free shipping\")\n```\n\n(The example is formatted using [Fantomas](https://fsprojects.github.io/fantomas/), which line-breaks fluent chains at\nmethod calls. While the readability of Faqt assertion chains could be slightly improved by manual formatting, entirely\nforegoing automatic formatting is not worth the slight benefit to readability.)\n\nDepending on the input, a `Faqt.AssertionFailedException` may be raised with one of these messages:\n\nIf customer is `External`:\n\n```\nAssertion failed.\nSubject: customer\nBecause: This function should only be called with internal customers\nShould: BeOfCase\nExpected: Internal\nBut was:\n  External:\n    Id: 1\n```\n\nIf `ContactInfo` is `None`:\n\n```\nAssertion failed.\nSubject:\n- customer\n- ContactInfo\nShould: BeSome\nBut was: None\n```\n\nIf `LastName` is not `Armstrong`:\n\n```\nAssertion failed.\nSubject:\n- customer\n- ContactInfo\n- Name.LastName\nBecause: Only customers named Armstrong get free shipping\nShould: Be\nExpected: Armstrong\nBut was: Aldrin\n```\n\nAs you can see, the output is YAML-based (because this is both human readable and works well for arbitrary structured\nvalues). The top-level `Subject` key tells you which part of the code fails, and an array of values is used when using\nderived state from an assertion, so you can track the transformations on the original subject.\n\n**Yes, this works even in Release mode or when source files are not available!** See the very simple requirements below.\n\n## Installation and requirements\n\n1. Install Faqt [from NuGet](https://www.nuget.org/packages/Faqt). Faqt supports .NET 5.0 and higher.\n2. If you use path mapping, deterministic source paths, or want to execute assertions where source files are not\n   available (e.g. in production), set `DebugType` to `embedded` and `EmbedAllSources` to `true`. For more details, see\n   the [documentation](DOCUMENTATION.md).\n\n## Faqt in a nutshell\n\nAs expected by the discerning F# developer, Faqt is:\n\n- **Readable:** Assertions read like natural language and clearly reveal their intention.\n- **Concise:** Assertion syntax verbosity is kept to an absolute minimum.\n- **Usable:** Faqt comes with batteries included, and contains many useful assertions, including aliases\n  (like `BeTrue()` for `Be(true)` on booleans, and `BeSome` for `BeOfCase(Some)` on `option` values).\n- **Safe:** Assertions are as type-safe as F# allows.\n- **Extensible:** No assertion? No problem! Writing your own assertions is very simple (details in\n  the [documentation](DOCUMENTATION.md)).\n- **Informative:** The assertion failure messages are designed to give you all the information you need in a consistent\n  and easy-to-read format.\n- **Discoverable:** The fluent syntax means you can just type a dot to discover all possible assertions and actions on\n  the current value.\n- **Composable:** As far as possible, assertions are orthogonal (they check one thing only). For example,\n  predicate-based collection assertions pass for empty collections, just like F#'s `Seq.forall` and similar. You can\n  chain assertions with `And`, `Whose`, `WhoseValue`, `That`, `Derived`, and `Subject`, assert on derived values with\n  assertions like `BeSome`, and compose assertions with higher-order assertions like `Satisfy` and `SatisfyAll`.\n- **Configurable:** You can configure, either globally or for a specific scope (such as a test), how assertion failure\n  messages are rendered, as well as other configuration. You can easily tweak the default rendering or completely\n  replace the formatter.\n- **Production-ready:** Faqt is very well tested and is highly unlikely to break your code, whether test or production.\n\n## Documentation\n\nSee the [documentation](DOCUMENTATION.md) for additional details, such as the list of assertions, how to use the\noptional `%` operator (alias for `ignore`), instructions on writing your own assertions, customizing the output format,\nsecurity considerations, and a FAQ with, among other things, a brief comparison with other assertion frameworks.\n\n## Contributing\n\nContributions are welcome! Please see the [contribution guidelines](CONTRIBUTING.md) before opening an issue or pull\nrequest.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmeeren%2FFaqt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmeeren%2FFaqt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmeeren%2FFaqt/lists"}