From d98c925a5a9ba82fd1b35dcbf69322e58a957872 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 13 Jul 2018 13:00:55 +0200 Subject: [PATCH] Add helper method for finding icons closes #3 --- lib/manifique/metadata.rb | 48 +++++++++++++++++++++++++ spec/manifique/metadata_spec.rb | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/lib/manifique/metadata.rb b/lib/manifique/metadata.rb index d61d14a..32aa60e 100644 --- a/lib/manifique/metadata.rb +++ b/lib/manifique/metadata.rb @@ -1,3 +1,4 @@ +require "pry" module Manifique class Metadata @@ -22,9 +23,56 @@ module Manifique end end + def select_icon(options={}) + if options[:type].nil? && options[:sizes].nil? && options[:purpose].nil? + raise ArgumentError, "Tell me what to do!" + end + + results = icons + + if options[:purpose] + results.reject! { |r| r["purpose"] != options[:purpose] } + else + # Do not return special icons by default + results.reject! { |r| r["purpose"] } + end + + if options[:type] + results.reject! { |r| r["type"] != options[:type] } + end + + if options[:sizes] + results.reject! { |r| r["sizes"].nil? } + results.sort! { |a, b| sizes_to_i(b["sizes"]) <=> sizes_to_i(a["sizes"]) } + + if icon = select_exact_size(results, options[:sizes]) + return icon + else + return select_best_size(results, options[:sizes]) + end + end + + results.first + end + def to_json # TODO serialize into JSON end + private + + def sizes_to_i(str) + str.match(/(\d+)x/)[1].to_i + end + + def select_exact_size(results, sizes) + results.select{|r| r["sizes"] == sizes}[0] + end + + def select_best_size(results, sizes) + results.reject! { |r| sizes_to_i(r["sizes"]) < sizes_to_i(sizes) } + results.last + end + end end diff --git a/spec/manifique/metadata_spec.rb b/spec/manifique/metadata_spec.rb index 1267ea8..254385f 100644 --- a/spec/manifique/metadata_spec.rb +++ b/spec/manifique/metadata_spec.rb @@ -38,4 +38,68 @@ RSpec.describe Manifique::Metadata do end end + describe "#select_icon" do + let(:metadata) { Manifique::Metadata.new } + + before do + metadata.icons = icon_fixtures + end + + it "expects at least one filter option" do + expect { metadata.select_icon }.to raise_error(ArgumentError) + end + + describe "by purpose" do + it "returns the correct icon" do + icon = metadata.select_icon(purpose: "mask-icon") + expect(icon["src"]).to eq("/mask-icon.svg") + end + end + + describe "by type" do + it "returns the largest image of the type" do + icon = metadata.select_icon(type: "image/png") + expect(icon["sizes"]).to eq("512x512") + end + end + + describe "by size" do + it "returns the exact size when available" do + icon = metadata.select_icon(sizes: "256x256") + expect(icon["sizes"]).to eq("256x256") + end + + it "returns the icon with the closest (but larger) size" do + icon = metadata.select_icon(sizes: "180x180") + expect(icon["sizes"]).to eq("192x192") + end + end + + describe "special purpose by size" do + it "returns the exact size when available" do + icon = metadata.select_icon(purpose: "apple-touch-icon", sizes: "180x180") + expect(icon["sizes"]).to eq("180x180") + end + + it "returns the icon with the closest (but larger) size" do + icon = metadata.select_icon(purpose: "apple-touch-icon", sizes: "44x44") + expect(icon["sizes"]).to eq("57x57") + end + end + end + +end + +def icon_fixtures + [ + {"src"=>"/favicon.ico", "sizes"=>nil, "type"=>"image/x-icon"}, + {"src"=>"/application_icon_x512.png", "sizes"=>"512x512", "type"=>"image/png"}, + {"src"=>"/application_icon_x256.png", "sizes"=>"256x256", "type"=>"image/png"}, + {"src"=>"/application_icon_x228.png", "sizes"=>"228x228", "type"=>"image/png"}, + {"src"=>"/application_icon_x196.png", "sizes"=>"196x196", "type"=>"image/png"}, + {"src"=>"/application_icon_x192.png", "sizes"=>"192x192", "type"=>"image/png"}, + {"purpose"=>"apple-touch-icon", "src"=>"/apple-touch-icon.png", "sizes"=>"180x180", "type"=>"image/png" }, + {"purpose"=>"apple-touch-icon", "src"=>"/apple-touch-icon-57px.png", "sizes"=>"57x57", "type"=>"image/png"}, + {"purpose"=>"mask-icon", "src"=>"/mask-icon.svg", "type"=>"image/svg", "color"=>"#2b90d9"} + ] end