{"id":13879666,"url":"https://github.com/socketry/async-rspec","last_synced_at":"2025-04-09T08:07:16.333Z","repository":{"id":21254981,"uuid":"92007548","full_name":"socketry/async-rspec","owner":"socketry","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-04T21:02:45.000Z","size":119,"stargazers_count":55,"open_issues_count":3,"forks_count":4,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-02T07:07:28.339Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/socketry.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.md","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":"2017-05-22T03:28:30.000Z","updated_at":"2025-03-04T21:02:48.000Z","dependencies_parsed_at":"2024-11-17T02:01:15.947Z","dependency_job_id":null,"html_url":"https://github.com/socketry/async-rspec","commit_stats":{"total_commits":93,"total_committers":5,"mean_commits":18.6,"dds":"0.16129032258064513","last_synced_commit":"66f0ac85218d087b7cc4a60736f2bf8d761acc76"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fasync-rspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fasync-rspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fasync-rspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fasync-rspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/socketry","download_url":"https://codeload.github.com/socketry/async-rspec/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247999859,"owners_count":21031046,"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":[],"created_at":"2024-08-06T08:02:28.275Z","updated_at":"2025-04-09T08:07:16.311Z","avatar_url":"https://github.com/socketry.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Async::RSpec\n\nProvides useful `RSpec.shared_context`s for testing code that builds on top of [async](https://github.com/socketry/async).\n\n[![Development Status](https://github.com/socketry/async-rspec/workflows/Test/badge.svg)](https://github.com/socketry/async-rspec/actions?workflow=Test)\n\n## Installation\n\n``` shell\n$ bundle add async-rspec\n```\n\nThen add this require statement to the top of `spec/spec_helper.rb`\n\n``` ruby\nrequire 'async/rspec'\n```\n\n## Usage\n\n### Async Reactor\n\nMany specs need to run within a reactor. A shared context is provided which includes all the relevant bits, including the above leaks checks. If your spec fails to run in less than 10 seconds, an `Async::TimeoutError` raises to prevent your test suite from hanging.\n\n``` ruby\nrequire 'async/io'\n\nRSpec.describe Async::IO do\n\tinclude_context Async::RSpec::Reactor\n\t\n\tlet(:pipe) {IO.pipe}\n\tlet(:input) {Async::IO::Generic.new(pipe.first)}\n\tlet(:output) {Async::IO::Generic.new(pipe.last)}\n\t\n\tit \"should send and receive data within the same reactor\" do\n\t\tmessage = nil\n\t\t\n\t\toutput_task = reactor.async do\n\t\t\tmessage = input.read(1024)\n\t\tend\n\t\t\n\t\treactor.async do\n\t\t\toutput.write(\"Hello World\")\n\t\tend\n\t\t\n\t\toutput_task.wait\n\t\texpect(message).to be == \"Hello World\"\n\t\t\n\t\tinput.close\n\t\toutput.close\n\tend\nend\n```\n\n### Changing Timeout\n\nYou can change the timeout by specifying it as an option:\n\n``` ruby\nRSpec.describe MySlowThing, timeout: 60 do\n\t# ...\nend\n```\n\n### File Descriptor Leaks\n\nLeaking sockets and other kinds of IOs are a problem for long running services. `Async::RSpec::Leaks` tracks all open sockets both before and after the spec. If any are left open, a `RuntimeError` is raised and the spec fails.\n\n``` ruby\nRSpec.describe \"leaky ios\" do\n\tinclude_context Async::RSpec::Leaks\n\t\n\t# The following fails:\n\tit \"leaks io\" do\n\t\t@input, @output = IO.pipe\n\tend\nend\n```\n\nIn some cases, the Ruby garbage collector will close IOs. In the above case, it's possible that just writing `IO.pipe` will not leak as Ruby will garbage collect the resulting IOs immediately. It's still incorrect to not close IOs, so don't depend on this behaviour.\n\n### Allocations\n\nThis functionality was moved to [`rspec-memory`](https://github.com/socketry/rspec-memory).\n\n## Contributing\n\nWe welcome contributions to this project.\n\n1.  Fork it.\n2.  Create your feature branch (`git checkout -b my-new-feature`).\n3.  Commit your changes (`git commit -am 'Add some feature'`).\n4.  Push to the branch (`git push origin my-new-feature`).\n5.  Create new Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsocketry%2Fasync-rspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsocketry%2Fasync-rspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsocketry%2Fasync-rspec/lists"}