{"id":16681876,"url":"https://github.com/tobz/tracing-fluent-assertions","last_synced_at":"2025-06-25T23:04:55.184Z","repository":{"id":44529090,"uuid":"432866854","full_name":"tobz/tracing-fluent-assertions","owner":"tobz","description":"A fluent assertions framework for tracing.","archived":false,"fork":false,"pushed_at":"2022-02-09T21:39:34.000Z","size":34,"stargazers_count":6,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-20T20:00:07.878Z","etag":null,"topics":["async","fluent-assertions","rust","tracing"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/tobz.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}},"created_at":"2021-11-29T01:14:57.000Z","updated_at":"2025-02-12T01:26:44.000Z","dependencies_parsed_at":"2022-09-12T15:43:27.332Z","dependency_job_id":null,"html_url":"https://github.com/tobz/tracing-fluent-assertions","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/tobz/tracing-fluent-assertions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobz%2Ftracing-fluent-assertions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobz%2Ftracing-fluent-assertions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobz%2Ftracing-fluent-assertions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobz%2Ftracing-fluent-assertions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tobz","download_url":"https://codeload.github.com/tobz/tracing-fluent-assertions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobz%2Ftracing-fluent-assertions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261410505,"owners_count":23154084,"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":["async","fluent-assertions","rust","tracing"],"created_at":"2024-10-12T14:05:33.822Z","updated_at":"2025-06-25T23:04:55.158Z","avatar_url":"https://github.com/tobz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tracing-fluent-assertions\nA fluent assertions framework for [`tracing`](https://docs.rs/tracing).\n\n## overview\n\nWhile there are already many crates that deal with testing -- mocks, test doubles, advanced\nassertions, etc -- there aren't any crates that allow a user to understand how their\n[`tracing`](https://docs.rs/tracing) implementation is exercised at a holistic level.  While there\nare some crates, like [`tracing-test`](https://docs.rs/tracing-test), which exist for figuring out\nif a chunk of code emitted certain events, there is no generic way to ask questions like:\n\n- was span A ever created? or entered?\n- did it ever close?\n- did it enter/exit/close at least N times?\n- did any spans in module path X ever get created?\n\nThis is the problem that `tracing-fluent-assertions` aims to solve.\n\n## usage\n\nThis crate doesn't look terribly dissimilar to other crates which provide fluent assertions, but as\nit's oriented around spans, which are callsite-defined, there's a little bit of boilerplate involved\nin using it compared to defining assertions directly against the result of a function, and so on.\n\nFirstly, it provides a [`Subscriber`](https://docs.rs/tracing/latest/tracing/trait.Subscriber.html)\nlayer that must be installed so that it can intercept span events and track the lifecycle of spans.\nSecondly, an\n[`AssertionRegistry`](https://docs.rs/tracing-fluent-assertions/latest/tracing_fluent_assertions/assertion/struct.AssertionRegistry.html)\nis provided for creating and storing assertions.\n\nAn\n[`Assertion`](https://docs.rs/tracing-fluent-assertions/latest/tracing_fluent_assertions/assertion/struct.Assertion.html\n) defines what spans it should match, and what behavior the spans must match in order to assert\nsuccessfully.\n\nA condensed usage might look something like this:\n\n```rust\nuse tracing_fluent_assertions::{AssertionLayer, AssertionRegistry};\nuse tracing_subscriber::{layer::SubscriberExt, Registry};\n\nfn main() {\n    // Create the assertion registry and install the assertion layer,\n    // then install that subscriber as the global default.\n    let assertion_registry = AssertionRegistry::default();\n    let base_subscriber = Registry::default();\n    let subscriber = base_subscriber.with(AssertionsLayer::new(\u0026assertion_registry));\n    tracing::subscriber::set_global_default(subscriber).unwrap();\n\n    // Create an assertion.  We'll look for a span called `shave_yak`,\n    // and assert that it's closed at least twice, signalling two full\n    // create/enter/exit/closed instances of the span.  Essentially, at\n    // least two yaks were completely shaved.\n    let more_than_one_shaved_yak = assertion_registry.build()\n        .with_name(\"shave_yak\")\n        .was_closed_many(2)\n        .finalize();\n\n    // Now, call our method that actually shaves the yaks.\n    shave_yaks(5);\n\n    // Assuming all five yaks were shaved, this assertion will pass,\n    // and no panic will be generated, yay!\n    more_than_one_yak_shaved.assert();\n\n    // An advanced usage of assertions can be to figure out when a span\n    // has finally been entered.  This can be useful for ascertaining when\n    // an asynchronous function has made it through other await points and\n    // is now waiting at a piece of code that we control, with its own span.\n    //\n    // For this, we can use the fallible `try_assert`, which won't panic\n    // if the assertion criteria has yet to be entirely met:\n    let reached_acquire_shaving_shears = assertion_registry.build()\n        .with_name(\"acquire_shaving_shears\")\n        .was_entered()\n        .finalize();\n\n    let manual_future = shave_yaks_async(5);\n\n    assert!(!reached_acquire_shaving_shears.try_assert());\n    while !reached_acquire_shaving_shears.try_assert() {\n        manual_future.poll();\n    }\n\n    // Once we break out of that loop, we know that we have entered the\n    // `acquire_shaving_shears` span at least once.  This example is a bit\n    // contrived, but a more useful scenario (albeit with more code required\n    // to demonstrate) would be to figure out that one asynchronous task is\n    // finally awaiting a specific resource, when it has to await other resources\n    // that can't be deterministically controlled when under test.\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobz%2Ftracing-fluent-assertions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftobz%2Ftracing-fluent-assertions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobz%2Ftracing-fluent-assertions/lists"}