{"id":14991364,"url":"https://github.com/dannyben/rspec_approvals","last_synced_at":"2025-04-12T03:32:19.526Z","repository":{"id":43366042,"uuid":"112834032","full_name":"DannyBen/rspec_approvals","owner":"DannyBen","description":"Interactive Approval Testing for RSpec","archived":false,"fork":false,"pushed_at":"2024-03-23T07:20:13.000Z","size":345,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-07T10:03:06.183Z","etag":null,"topics":["approval-testing","approvals","gem","rspec","rspec-fixtures","ruby"],"latest_commit_sha":null,"homepage":"","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/DannyBen.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-02T10:42:59.000Z","updated_at":"2024-09-20T09:07:06.000Z","dependencies_parsed_at":"2024-03-23T08:37:28.319Z","dependency_job_id":null,"html_url":"https://github.com/DannyBen/rspec_approvals","commit_stats":{"total_commits":138,"total_committers":2,"mean_commits":69.0,"dds":0.3913043478260869,"last_synced_commit":"8d6d1ea974f8df77d6fed59eb25dc1b0f90bdc7e"},"previous_names":["dannyben/rspec_fixtures"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Frspec_approvals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Frspec_approvals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Frspec_approvals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Frspec_approvals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DannyBen","download_url":"https://codeload.github.com/DannyBen/rspec_approvals/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223494315,"owners_count":17154526,"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":["approval-testing","approvals","gem","rspec","rspec-fixtures","ruby"],"created_at":"2024-09-24T14:27:32.978Z","updated_at":"2024-11-07T10:04:53.858Z","avatar_url":"https://github.com/DannyBen.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RSpec Approvals\n\n[![Gem Version](https://badge.fury.io/rb/rspec_approvals.svg)](https://badge.fury.io/rb/rspec_approvals)\n[![Build Status](https://github.com/DannyBen/rspec_approvals/workflows/Test/badge.svg)](https://github.com/DannyBen/rspec_approvals/actions?query=workflow%3ATest)\n[![Maintainability](https://api.codeclimate.com/v1/badges/b6ca26de93d9236c706a/maintainability)](https://codeclimate.com/github/DannyBen/rspec_approvals/maintainability)\n\n---\n\nRSpec Approvals allows you to interactively review and approve testable\ncontent. \n\n![Demo](demo/cast.svg)\n\n---\n\n## Install\n\n```\n$ gem install rspec_approvals\n```\n\nOr with bundler:\n\n```ruby\ngem 'rspec_approvals'\n```\n\n## Usage\n\nRequire the gem in your spec helper:\n\n```ruby\n# spec/spec_helper.rb\nrequire 'rspec_approvals'\n```\n\nAnd use any of the matchers in your specs.\n\n```ruby\ndescribe 'ls' do\n  it \"works\" do\n    expect(`ls`).to match_approval('ls_approval')\n  end\nend\n```\n\n## Matchers\n\n### `match_approval` - Compare Strings\n\nCompare a string with a pre-approved approval.\n\n```ruby\nexpect('some string').to match_approval('approval_filename')\n```\n\n\n### `output_approval` - Compare STDOUT/STDERR\n\nCompare an output (stdout or stderr) with a pre-approved approval.\n\n```ruby\nexpect { puts \"hello\" }.to output_approval('approval_filename')\nexpect { puts \"hello\" }.to output_approval('approval_filename').to_stdout\nexpect { $stderr.puts \"hello\" }.to output_approval('approval_filename').to_stderr\n\n# The first two are the same, as the default stream is stdout.\n```\n\n\n### `raise_approval` - Compare raised exceptions\n\nCompare a raised exception with a pre-approved approval.\n\n```ruby\nexpect { raise 'some error' }.to raise_approval('approval_filename')\n```\n\n## Modifiers\n\n### `diff` - String similarity\n\nAdding `diff(distance)` to either `match_approval` or `output_approval` will\nchange the matching behavior. Instead of expecting the strings to be exactly\nthe same, using `diff` compares the strings using the \n[Levenshtein distance][levenshtein] algorithm.\n\nIn the below example, we allow up to 5 characters to be different.\n\n```ruby\nexpect ('some string').to match_approval('approval_filename').diff(5)\nexpect { puts 'some string' }.to output_approval('approval_filename').diff(5)\n```\n\n### `except` - Exclude by regular expression\n\nAdding `except(regex)` to either `match_approval` or `output_approval` will\nmodify the string under test before running. By default, the regular\nexpression will be replaced with `...`.\n\nIn the below example, we ignore the full path of the file.\n\n```ruby\nexpect('path: /path/to/file').to match_approval('approval_filename').except(/path: .*file/)\n```\n\nYou may provide a second argument, which will be used as an alternative\nreplace string:\n\nIn the below example, all time strings will be replaced with `HH:MM`:\n\n```ruby\nexpect('22:30').to match_approval('approval_filename').except(/\\d2:\\d2/, 'HH:MM')\n```\n\n### `before` - Alter the string before testing\n\nThe `before(proc)` method is a low level method and should normally not be \nused directly (as it is used by the `except` modifier).\n\nAdding `before(proc)` to either `match_approval` or `output_approval` will\ncall the block and supply the actual string. The proc is expected to return\nthe new actual string.\n\nIn the below example, we replace all email addresses in a string.\n\n```ruby\nexpect('hello rspec@approvals.com').to match_approval('approval_filename').before -\u003e(actual) do\n  actual.gsub /\\w+@\\w+\\.\\w+/, 'some@email.com'\nend\n\n```\n\n## Configuration\n\n### `interactive_approvals`\n\nBy default, interactive approvals are enabled in any environment that \ndoes not define the `CI` or the `GITHUB_ACTIONS` environment variables.\nYou can change this by adding this to your `spec_helper`\n\n```ruby\nRSpec.configure do |config|\n  config.interactive_approvals = false # or any logic\nend\n```\n\n### `approvals_path`\n\nBy default, approvals are stored in `spec/approvals`. To change the path,\nadd this to your `spec_helper`.\n\n```ruby\nRSpec.configure do |config|\n  config.approvals_path = 'spec/anywhere/else'\nend\n```\n\n### `auto_approve`\n\nIf you wish to automatically approve all new or changed approvals, you can\nset the `auto_approve` configuration option to `true`. By default, \nauto approval is enabled if the environment variable `AUTO_APPROVE` is set.\n\n```ruby\nRSpec.configure do |config|\n  config.auto_approve = true # or any logic\nend\n```\n\nThis feature is intended to help clean up the approvals folder from old, no\nlonger used files. Simply run the specs once, to ensure they all oass, \ndelete the approvals folder, and run the specs again with:\n\n```\n$ AUTO_APPROVE=1 rspec\n```\n\n### `strip_ansi_escape`\n\nIn case your output strings contain ANSI escape codes that you wish to avoid\nstoring in your approvals, you can set the `strip_ansi_escape` to `true`.\n\n```ruby\nRSpec.configure do |config|\n  config.strip_ansi_escape = true\nend\n```\n\n### `before_approval`\n\nIn case you need to alter the actual output globally, you can provide the\n`before_approval` option with a proc. The proc will receive the actual\noutput - similarly to the `before` modifier - and is expectedd to return\na modified actual string.\n\n```ruby\nRSpec.configure do |config|\n  config.before_approval = -\u003e(actual) do\n    # return the actual string, without IP addresses\n    actual.gsub(/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/, '[IP REMOVED]')\n  end\nend\n```\n\n## Advanced Usage Tips\n\n### Sending output directly to RSpecApprovals\n\nIn some cases, you might need to send output directly to the `RSpecApproval`\nstream capturer.\n\nAn example use case, is when you are testing `Logger` output.\n\nThe `RSpecApproval#stdout` and `RSpecApproval#stderr` can be used as an\nalternative to `$stdout` and `$stderr`. These methods both return the\n`StringIO` object that is used by `RSpecApprovals` to capture the output.\n\nFor example, you can use this:\n\n```ruby\nlogger = Logger.new(RSpecApprovals.stdout)\n```\n\nas an alternative to this:\n\n```\nlogger = Logger.new($stdout)\n```\n\n### Consistent terminal width\n\nIn case you are testing standard output with long lines, you may encounter inconsistencies when testing on different hosts, with varying terminal width. In order to ensure consistent output to stdout, you may want to set a known terminal size in your `spec_helper`:\n\n```ruby\nENV['COLUMNS'] = '80'\nENV['LINES'] = '24'\n```\n\n### Recommended rspec flags\n\nFor best results, it is recommended you configure rspec to use the\ndocumentation format. Place the code below in a file named `.rspec`\nin your project's directory:\n\n```\n--color\n--format documentation\n```\n\n## Contributing / Support\n\nIf you experience any issue, have a question or a suggestion, or if you wish\nto contribute, feel free to [open an issue][issues].\n\n\n[levenshtein]: https://en.wikipedia.org/wiki/Levenshtein_distance\n[issues]: https://github.com/DannyBen/rspec_approvals/issues\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdannyben%2Frspec_approvals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdannyben%2Frspec_approvals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdannyben%2Frspec_approvals/lists"}