Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making the snapshot name optional #6

Open
hooptie45 opened this issue Jun 8, 2017 · 7 comments
Open

Making the snapshot name optional #6

hooptie45 opened this issue Jun 8, 2017 · 7 comments

Comments

@hooptie45
Copy link

In jest, if you can omit the snapshot name; it'll derive it from the example name. Is that behavior supported? If it isn't, I'd be happy to help build that support. Thoughts?

@yesmeck
Copy link
Contributor

yesmeck commented Jun 9, 2017

PR is welcome.

@tncbbthositg
Copy link

Is this being worked on? If not, I'll probably add this early next week.

@yesmeck
Copy link
Contributor

yesmeck commented Jul 4, 2017

@tncbbthositg Welcome PR!

@rrcobb
Copy link

rrcobb commented Jan 19, 2018

Seconded!

@edmorley
Copy link

edmorley commented Jan 3, 2021

This would be a great feature. Is RSpec.current_example.description the correct way to access this metadata from within the matcher?

@levinmr
Copy link
Owner

levinmr commented Jun 22, 2021

Agree that this would be a useful feature. The way jest does it is to use the spec file name as the snapshot name and then treat the snapshot file like a hash using the example descriptions as the keys.

Will put this on the roadmap for the next version

@bbugh
Copy link

bbugh commented Feb 22, 2022

vcr has a common pattern for generating names of cassettes from the rspec example.

# probably already have this in the code
example = RSpec.current_example

# get the description (name) or the scoped id (like 1:2:4:8) 
path_data = [example.metadata[:description] || example.metadata[:scoped_id]]
parent = example.example_group

base_path = ""
while parent != RSpec::ExampleGroups
  base_path = File.dirname(parent.file_path.gsub("./spec/", ""))

  path_data << parent.metadata[:description]
  parent = parent.module_parent
end

path_data << base_path if base_path.present?

# Need to do this differently since it's a Rails thing
path_data = path_data.map { ActiveStorage::Filename.new(_1).sanitized }

# path_data is ['renders_component', 'when rating is > 0', 'StarRatingComponent', 'components']
name = path_data.reverse.join("/")

expect(rendered_component).to match_snapshot(name)

Will output a file to

spec/components/__snapshots__/components/StarRatingComponent/when rating is > 0/renders component.snap

although I have all of my snapshots going to spec/snapshots so it's

spec/snapshots/components/StarRatingComponent/when rating is > 0/renders component.snap

There's also another common vcr-ism that is probably nicer for the default folder setup:

name =
  RSpec.current_example
        .metadata[:full_description]
        .split(/\s+/, 2)
        .join("/")
        .underscore.tr(".", "/")
        .gsub(%r{[^\w/]+}, "_")
        .gsub(%r{/$}, "")

that results in

./spec/components/__snapshots__/star_rating_component/when_rating_is_0_renders_component.snap

This one can have collisions though, for example if you had a context "when rating is >= 0" and "when rating is < 0" the names would be the same because it's aggressive about stripping characters regardless of safety. This issue could be fixed by sanitizing the name like ActiveStorage::Filename so it doesn't strip out meaningful but filename-safe characters. (surprisingly, Ruby's stdlib doesn't have a filename sanitizer.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants