# frozen_string_literal: true require "spec_helper" require "roadie/rspec" module Roadie describe ProviderList do let(:test_provider) { TestProvider.new } subject(:provider) { ProviderList.new([test_provider]) } it_behaves_like "roadie asset provider", valid_name: "valid", invalid_name: "invalid" do let(:test_provider) { TestProvider.new "valid" => "" } end it "finds using all given providers" do first = TestProvider.new "foo.css" => "foo { color: green; }" second = TestProvider.new "bar.css" => "bar { color: green; }" provider = ProviderList.new [first, second] expect(provider.find_stylesheet("foo.css").to_s).to include "foo" expect(provider.find_stylesheet("bar.css").to_s).to include "bar" expect(provider.find_stylesheet("baz.css")).to be_nil end it "is enumerable" do expect(provider).to be_kind_of(Enumerable) expect(provider).to respond_to(:each) expect(provider.each.to_a).to eq([test_provider]) end it "has a size" do expect(provider.size).to eq(1) expect(provider).not_to be_empty end it "has a first and a last element" do providers = [double("1"), double("2"), double("3")] list = ProviderList.new(providers) expect(list.first).to eq(providers.first) expect(list.last).to eq(providers.last) end it "can have providers pushed and popped" do other = double "Some other provider" expect { provider.push other provider << other }.to change(provider, :size).by(2) expect { expect(provider.pop).to eq(other) }.to change(provider, :size).by(-1) end it "can have providers shifted and unshifted" do other = double "Some other provider" expect { provider.unshift other }.to change(provider, :size).by(1) expect { expect(provider.shift).to eq(other) }.to change(provider, :size).by(-1) end it "has a readable string represenation" do provider = double("Provider", to_s: "Some provider") sublist = ProviderList.new([provider, provider]) list = ProviderList.new([provider, sublist, provider]) expect(list.to_s).to eq(<<~TEXT) ProviderList: [ \tSome provider, \tProviderList: [ \t\tSome provider, \t\tSome provider \t], \tSome provider ] TEXT end it "raises a readable error message" do provider = double("Provider", to_s: "Some provider") allow(provider).to receive(:find_stylesheet!).and_raise( CssNotFound.new( css_name: "style.css", message: "I tripped", provider: provider ) ) sublist = ProviderList.new([provider, provider]) list = ProviderList.new([provider, sublist, provider]) expect { list.find_stylesheet!("style.css") }.to raise_error { |error| expect(error.message).to eq(<<~TEXT) Could not find stylesheet "style.css": All providers failed Used providers: \tSome provider: I tripped \tSome provider: I tripped \tSome provider: I tripped \tSome provider: I tripped TEXT } end describe "wrapping" do it "creates provider lists with the arguments" do expect(ProviderList.wrap(test_provider)).to be_instance_of(ProviderList) expect(ProviderList.wrap(test_provider, test_provider).size).to eq(2) end it "flattens arrays" do expect(ProviderList.wrap([test_provider, test_provider], test_provider).size).to eq(3) expect(ProviderList.wrap([test_provider, test_provider]).size).to eq(2) end it "combines with providers from other lists" do other_list = ProviderList.new([test_provider, test_provider]) expect(ProviderList.wrap(test_provider, other_list).size).to eq(3) end it "returns the passed list if only a single ProviderList is passed" do other_list = ProviderList.new([test_provider]) expect(ProviderList.wrap(other_list)).to eql other_list end end end end