diff --git a/README.md b/README.md index 8208c58..d2dad47 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,11 @@ RSpec.configure do |config| # Set this value to put all snapshots in a fixed directory config.snapshot_dir = "spec/fixtures/snapshots" + # Defaults to not applying any additional formatting + # + # Set this value to use a custom formatter for when `expect` receives a string + config.snapshot_formatter = MyFavoriteFormatter + # Defaults to using the awesome_print gem to serialize values for snapshots # # Set this value to use a custom snapshot serializer @@ -114,18 +119,31 @@ You can pass custom serializers to `rspec-snapshot` if you prefer. Pass a serial matcher as a config option: ```ruby +# Set a custom string formatter for all tests +RSpec.configure do |config| + config.snapshot_formatter = MyCoolGeneralFormatter +end + # Set a custom serializer for all tests RSpec.configure do |config| config.snapshot_serializer = MyCoolGeneralSerializer end -# Set a custom serializer for this specific test +# Set a custom formatter for this specific test expect(html_response).to( - match_snapshot('html_response', { snapshot_serializer: MyAwesomeHTMLSerializer }) + match_snapshot('html_response', { snapshot_formatter: MyAwesomeFormatter }) +) + +# Set a custom serializer for this specific test +expect(result_object).to( + match_snapshot('result_object', { snapshot_serializer: MyAwesomeSerializer }) ) ``` -Serializer classes are required to have one instance method `dump` which takes +Formatters are required to have a single `call` method that takes the raw string value +and returns a formatted string. If you want, you can use a proc or lambda. + +Serializer classes are required to have one instance method `dump`, which takes the value to be serialized and returns a string. ## Migration diff --git a/lib/rspec/snapshot/configuration.rb b/lib/rspec/snapshot/configuration.rb index 2b5dcd2..8b80a15 100644 --- a/lib/rspec/snapshot/configuration.rb +++ b/lib/rspec/snapshot/configuration.rb @@ -10,6 +10,8 @@ class Configuration; end def self.initialize_configuration(config) config.add_setting :snapshot_dir, default: :relative + config.add_setting :snapshot_formatter, default: nil + config.add_setting :snapshot_serializer, default: nil end diff --git a/lib/rspec/snapshot/matchers/match_snapshot.rb b/lib/rspec/snapshot/matchers/match_snapshot.rb index fc24673..bacca75 100644 --- a/lib/rspec/snapshot/matchers/match_snapshot.rb +++ b/lib/rspec/snapshot/matchers/match_snapshot.rb @@ -14,11 +14,22 @@ def initialize(metadata, snapshot_name, config) @metadata = metadata @snapshot_name = snapshot_name @config = config + @formatter = formatter @serializer = serializer_class.new @snapshot_path = File.join(snapshot_dir, "#{@snapshot_name}.snap") create_snapshot_dir end + private def formatter + if @config[:snapshot_formatter] + @config[:snapshot_formatter] + elsif RSpec.configuration.snapshot_formatter + RSpec.configuration.snapshot_formatter + else + ->(value) { value } + end + end + private def serializer_class if @config[:snapshot_serializer] @config[:snapshot_serializer] @@ -44,7 +55,7 @@ def initialize(metadata, snapshot_name, config) end def matches?(actual) - @actual = serialize(actual) + @actual = serialize(format(actual)) write_snapshot @@ -56,6 +67,14 @@ def matches?(actual) # === is the method called when matching an argument alias === matches? + private def format(value) + if value.is_a?(String) + @formatter.call(value) + else + value + end + end + private def serialize(value) if value.is_a?(String) value