require 'spec_helper' describe SumSum do context ".new" do it "should raise no error with zero argument" do lambda{ SumSum.new }.should_not raise_error(ArgumentError) end it "should raise no error with one argument" do lambda{ SumSum.new(:x) }.should_not raise_error end it "should raise no error with multiple argument" do lambda{ SumSum.new(:x, :y, :z) }.should_not raise_error end end let(:sum) { SumSum.new(:type, :name, :version) } context "adding single hash" do before do sum.add({:type => :Browser, :name => :Firefox, :version => "3.6.0"}) end context "#count" do it "should return 1 on all levels" do sum.count.should eql(1) sum[:Browser].count.should eql(1) sum[:Browser][:Firefox].count.should eql(1) sum[:Browser][:Firefox]["3.6.0"].count.should eql(1) end end context "#keys" do it "should return correct keys on all levels" do sum.keys.should eql([:Browser]) sum[:Browser].keys.should eql([:Firefox]) sum[:Browser][:Firefox].keys.should eql(["3.6.0"]) sum[:Browser][:Firefox]["3.6.0"].keys.should eql([]) end end context "#dump" do it "should output serializable array" do sum.dump.should eql( [[:type, :name, :version], {:Browser=>{:Firefox=>{"3.6.0"=>1}}}] ) end end context ".load" do it "should restore everything from serializable array" do SumSum.load(sum.dump).dump.should eql(sum.dump) end end end context "adding multiple hashes" do before do sum.add({:type => :Crawler, :name => :GoogleBot, :version => "2.0"}) sum.add({:type => :Browser, :name => :Firefox, :version => "3.6.0"}) sum.add({:type => :Browser, :name => :Safari, :version => "4.0"}) sum.add({:type => :Browser, :name => :Safari, :version => "5.0"}) sum.add({:type => :Browser, :name => :Safari, :version => "5.0"}) end context "#add" do it "should return itself" do sum.add({:type => :Crawler, :name => :GoogleBot, :version => "2.0"}).should eql(sum) end it "should add missing values as nil" do sum.add({:type => :Crawler, :name => nil}) sum.add({:type => :Crawler}) sum[:Crawler].keys.should eql([:GoogleBot, nil]) sum[:Crawler][nil].count.should eql(2) sum[:Crawler][nil].keys.should eql([nil]) sum[:Crawler][nil][nil].count.should eql(2) end it "should allow to add multiple counts at once" do sum.add({:type => :Crawler, :name => :DuckDuckGo, :version => "1.0"}, 10) sum[:Crawler].count.should eql(11) sum[:Crawler][:DuckDuckGo].count.should eql(10) sum[:Crawler][:DuckDuckGo]["1.0"].count.should eql(10) end end context "#count" do it "should return correct count on all levels" do sum.count.should eql(5) sum[:Browser].count.should eql(4) sum[:Browser][:Firefox].count.should eql(1) sum[:Browser][:Firefox]["3.6.0"].count.should eql(1) sum[:Browser][:Safari].count.should eql(3) sum[:Browser][:Safari]["5.0"].count.should eql(2) sum[:Browser][:Safari]["4.0"].count.should eql(1) sum[:Crawler].count.should eql(1) sum[:Crawler][:GoogleBot].count.should eql(1) sum[:Crawler][:GoogleBot]["2.0"].count.should eql(1) end end context "#keys" do it "should return correct keys on all levels" do sum.keys.should eql([:Crawler, :Browser]) sum[:Browser].keys.should eql([:Firefox, :Safari]) sum[:Browser][:Firefox].keys.should eql(["3.6.0"]) sum[:Browser][:Firefox]["3.6.0"].keys.should eql([]) sum[:Browser][:Safari].keys.should eql(["4.0", "5.0"]) sum[:Browser][:Safari]["4.0"].keys.should eql([]) sum[:Browser][:Safari]["5.0"].keys.should eql([]) sum[:Crawler].keys.should eql([:GoogleBot]) sum[:Crawler][:GoogleBot].keys.should eql(["2.0"]) sum[:Crawler][:GoogleBot]["2.0"].keys.should eql([]) end end context "#sort" do before do sum.add({:type => :Browser, :name => :Safari, :version => "5.0.3"}, 3) sum.add({:type => :Browser, :name => :Chrome, :version => "5.0"}, 2) sum.sort! end it "should sort by count" do sum.keys.should eql([:Browser, :Crawler]) sum[:Browser].keys.should eql([:Safari, :Chrome, :Firefox]) sum[:Browser][:Safari].keys.should eql(["5.0.3", "5.0", "4.0"]) end end context "#share" do it "should return 1.0 on root" do sum.share.should eql(1.0) end it "should return 1.0 on branch with single entry" do sum[:Crawler][:GoogleBot].share.should eql(1.0) end it "should return 0.2 on branch with one out of five" do sum[:Crawler].share.should eql(0.2) end it "should return 0.8 on branch with four out of five" do sum[:Browser].share.should eql(0.8) end it "should return 0.25 on branch with one out of four" do sum[:Browser][:Firefox].share.should eql(0.25) end end context "#dump" do it "should output serializable array" do sum.dump.should eql( [[:type, :name, :version], { :Crawler=>{:GoogleBot=>{"2.0"=>1}}, :Browser=>{ :Firefox=>{"3.6.0"=>1}, :Safari=>{"4.0"=>1, "5.0"=>2} } }] ) end end context ".load" do it "should restore everything from serializable array" do SumSum.load(sum.dump).dump.should eql(sum.dump) end end end end