Webp and picture tags in a rails app

<picture>  <source srcset=”path_to_image.webp” >  <img src=”path_to_image.png’” alt=”alt text” ></picture>
<picture>  <source srcset=”path_to_version_one.webp”>  <source srcset=”path_to_image.webp” >  <img src=”path_to_image.png’” alt=”alt text” ></picture>
let(:picture_object) do  double(    'Photo',     versions: {       thumb: thumb,       thumb_webp: thumb_webp,       medium: medium,       medium_webp: medium_webp,       other: other     },     url: 'https://original_version.jpeg',     exists?: true  )endlet(:webp_file) { double('webp_file', extension: 'webp') }let(:jpeg_file) { double('jpeg_file', extension: 'jpeg') }let(:thumb) { double('thumb', url: 'https://thumb_url.jpg', file: jpeg_file) }let(:thumb_webp) { double('thumb_webp', url: 'https://thumb_url.webp', file: webp_file) }let(:medium_webp) { double('medium_webp', url: 'https://medium_url.webp', file: webp_file) }let(:medium) { double('medium', url: 'https://medium_url.jpg', file: jpeg_file) }let(:other) { double('other', url: 'https://other_url.jpg', file: jpeg_file) }
it ‘responds with a picture tag’ do  expect(helper.picture_tag(picture_object)).to include(‘<picture>’)  expect(helper.picture_tag(picture_object)).to include(‘</picture>’)end
def picture_tag(picture)  tag.pictureend
picture of passing tests in a terminal
# frozen_string_literal: truerequire 'rails_helper'RSpec.describe Pictures::PictureTagHelper, type: :helper do describe '#picture_tag' do  let(:picture_object) do   double(    'Photo',    versions: {     thumb: thumb,     thumb_webp: thumb_webp,     medium: medium,     medium_webp: medium_webp,     other: other    },    url: 'https://original_version.jpeg',    exists?: true   )  end  let(:webp_file) { double('webp_file', extension: 'webp') }  let(:jpeg_file) { double('jpeg_file', extension: 'jpeg') }  let(:thumb) { double('thumb', url: 'https://thumb_url.jpg', file: jpeg_file) }  let(:thumb_webp) { double('thumb_webp', url: 'https://thumb_url.webp', file: webp_file) }  let(:medium_webp) { double('medium_webp', url: 'https://medium_url.webp', file: webp_file) }  let(:medium) { double('medium', url: 'https://medium_url.jpg', file: jpeg_file) }  let(:other) { double('other', url: 'https://other_url.jpg', file: jpeg_file) }  it 'responds with a picture tag' do   expect(helper.picture_tag(picture_object)).to include('<picture>')   expect(helper.picture_tag(picture_object)).to include('</picture>')  end  context 'without versions' do   it 'should have an img tag' do    expect(     helper.picture_tag(      picture_object, image: { alt: 'alt message', width: 300,height: 300 }     )    ).to include('<img alt="alt message" width="300" height="300" src="https://original_version.jpeg" />')   end   it 'should have a source tag and file_type per version ' do    expect(helper.picture_tag(picture_object)).to include(     '<source srcset="https://thumb_url.jpg" type="image/jpeg">'    )    expect(helper.picture_tag(picture_object)).to include(     '<source srcset="https://thumb_url.webp" type="image/webp">'    )    expect(helper.picture_tag(picture_object)).to include(     '<source srcset="https://medium_url.webp" type="image/webp">'    )    expect(helper.picture_tag(picture_object)).to include(     '<source srcset="https://medium_url.jpg" type="image/jpeg">'    )    expect(helper.picture_tag(picture_object)).to include(     '<source srcset="https://other_url.jpg" type="image/jpeg">'    )   end  end  context 'with options' do   context 'with versions option' do    context 'without extensions not flagged' do     it 'accepts symbols' do      expect(       helper.picture_tag(        picture_object, versions: %i[thumb thumb_webp]       )      ).to include('<source srcset="https://thumb_url.jpg" type="image/jpeg">')     end     it 'should have the selected_version with all extensions' do      expect(       helper.picture_tag(        picture_object, versions: [:thumb]       )      ).to include(       '<source srcset="https://thumb_url.webp" type="image/webp">'\       '<source srcset="https://thumb_url.jpg" type="image/jpeg">'      )     end     it 'in the correct order' do      expect(       helper.picture_tag(        picture_object, versions: %i[medium thumb]       )      ).to include(       '<source srcset="https://medium_url.webp" type="image/webp">'\       '<source srcset="https://medium_url.jpg" type="image/jpeg">'\       '<source srcset="https://thumb_url.webp" type="image/webp">'\       '<source srcset="https://thumb_url.jpg" type="image/jpeg">'      )     end     it 'should not have the versions not included' do      expect(       helper.picture_tag(        picture_object, versions: [:thumb]       )      ).not_to include('<source srcset="https://medium_url.jpg" type="image/jpeg">')      expect(       helper.picture_tag(        picture_object, versions: %i[thumb medium]       )      ).not_to include('<source srcset="https://other_url.webp" type="image/jpeg">')     end    end    context 'without extensions flagged' do     it 'accepts symbols' do      expect(       helper.picture_tag(        picture_object, without_extensions: true,        versions: %i[thumb thumb_webp]       )      ).to include('<source srcset="https://thumb_url.jpg" type="image/jpeg">')     end     it 'should have the selected_version' do      expect(       helper.picture_tag(        picture_object, without_extensions: true,        versions: [:thumb]       )      ).to include('<source srcset="https://thumb_url.jpg" type="image/jpeg">')     end     it 'in the correct order' do      expect(       helper.picture_tag(        picture_object, without_extensions: true,        versions: %i[medium thumb]       )      ).to include(       '<source srcset="https://medium_url.jpg" type="image/jpeg">'\       '<source srcset="https://thumb_url.jpg" type="image/jpeg">'      )     end     it 'should not have the versions not included' do      expect(       helper.picture_tag(        picture_object, without_extensions: true,        versions: [:thumb]       )      ).not_to include('<source srcset="https://medium_url.jpg" type="image/jpeg">')      expect(       helper.picture_tag(        picture_object, without_extensions: true,        versions: [:thumb]
)
).not_to include('<source srcset="https://thumb_url.webp" type="image/webp">') expect( helper.picture_tag( picture_object, without_extensions: true, versions: %i[thumb medium] ) ).not_to include('<source srcset="https://other_url.webp" type="image/jpeg">') end end end end endend
# frozen_string_literal: truemodule Pictures # These helpers help you build versions of # a picture in order to user the 'picture' tag module PictureTagHelper  # Possible options:  #  - versions (should be a version existing  # in the carrierwave uploader) [Array] of symbols or strings, order is important!  # - without_extensions [Boolean] if true does not add  # webp version (webp version must exist on the uploader),  # other extensions can be easily added  def picture_tag(picture, **options)   image_options = options[:image] || {}   return image_tag(picture.default_url, image_options) unless picture.exists?   picture_options = options[:picture] || {}   tag.picture(picture_options) do    "#{build_source_tags(picture, options).join}"\    " #{image_tag(picture.url, image_options)}".html_safe   end  end  # Possible options:  #  - versions (should be a version existing  # in the carrierwave uploader) [Array] of symbols or strings, order is important!  # - without_extensions [Boolean] if true does not add  # webp version (webp version must exist on the uploader),  # other extensions can be easily added  def source_tags(picture, **options)   build_source_tags(picture, options).join.to_s.html_safe  end  private  def build_source_tags(picture, options)   versions(picture, options).map do |_version_name, version_object|    source_tag(version_object)   end  end  def versions(picture, options)   return picture.versions.slice(*build_extensions(options)) if options[:versions]   picture.versions  end  def source_tag(version)   return '' unless version.file   tag.source srcset: version.url.gsub(/\(|\)/, '_'), type: image_type(version.file.extension)  end  def image_type(extension)   Mime::Type.register 'image/webp', :webp   Mime::Type.lookup_by_extension(extension).to_s  end  def build_extensions(options)   return options[:versions] if options[:without_extensions]   options[:versions].flat_map do |version|    ordered_extentions.map { |extension| "#{version}_#{extension}".to_sym } << version.to_sym   end  end  def ordered_extentions   ['webp']  end endend

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store