diff --git a/lib/cucumber/glue/snippet.rb b/lib/cucumber/glue/snippet.rb index f3995c1647..c61d0e47a5 100644 --- a/lib/cucumber/glue/snippet.rb +++ b/lib/cucumber/glue/snippet.rb @@ -91,7 +91,7 @@ def typed_pattern def to_s header = generated_expressions.each_with_index.map do |expr, i| prefix = i.zero? ? '' : '# ' - "#{prefix}#{code_keyword}('#{expr.source}') do#{parameters(expr)}" + "#{prefix}#{code_keyword}(#{quoted_expression_source(expr)}) do#{parameters(expr)}" end.join("\n") body = <<~DOC.chomp @@ -108,6 +108,15 @@ def parameters(expr) parameter_names.empty? ? '' : " |#{parameter_names.join(', ')}|" end + def quoted_expression_source(expr) + source = expr.source + + return "'#{source.gsub(/\\/) { |char| "\\#{char}" }}'" unless source.include?("'") + + escaped_source = source.gsub(/["\\#]/) { |char| "\\#{char}" } + "\"#{escaped_source}\"" + end + def self.description 'Cucumber Expressions' end diff --git a/spec/cucumber/glue/snippet_spec.rb b/spec/cucumber/glue/snippet_spec.rb index 651426bfa3..fb27bf017b 100644 --- a/spec/cucumber/glue/snippet_spec.rb +++ b/spec/cucumber/glue/snippet_spec.rb @@ -180,6 +180,39 @@ module Glue expect(snippet.to_s).to eq(cucumber_output) end + + it 'uses double quotes for generated snippets with apostrophes' do + @step_text = "Lucy hears Sean's message" + cucumber_output = <<~CUKE.chomp + Given("Lucy hears Sean's message") do + pending # Write code here that turns the phrase above into concrete actions + end + CUKE + + expect(snippet.to_s).to eq(cucumber_output) + end + + it 'escapes backslashes in single quoted snippets' do + @step_text = 'Lucy hears trailing \\' + cucumber_output = <<~'CUKE'.chomp + Given('Lucy hears trailing \\') do + pending # Write code here that turns the phrase above into concrete actions + end + CUKE + + expect(snippet.to_s).to eq(cucumber_output) + end + + it 'escapes interpolation markers in double quoted snippets' do + @step_text = 'Lucy hears Sean\'s #@message' + cucumber_output = <<~'CUKE'.chomp + Given("Lucy hears Sean's \#@message") do + pending # Write code here that turns the phrase above into concrete actions + end + CUKE + + expect(snippet.to_s).to eq(cucumber_output) + end end end end