sum_sum 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.2@sum_sum
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sum_sum.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sum_sum (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ configuration (1.2.0)
10
+ diff-lcs (1.1.2)
11
+ growl (1.0.3)
12
+ guard (0.3.0)
13
+ open_gem (~> 1.4.2)
14
+ thor (~> 0.14.6)
15
+ guard-rspec (0.1.9)
16
+ guard (>= 0.2.2)
17
+ launchy (0.3.7)
18
+ configuration (>= 0.0.5)
19
+ rake (>= 0.8.1)
20
+ open_gem (1.4.2)
21
+ launchy (~> 0.3.5)
22
+ rake (0.8.7)
23
+ rb-fsevent (0.3.9)
24
+ rspec (2.4.0)
25
+ rspec-core (~> 2.4.0)
26
+ rspec-expectations (~> 2.4.0)
27
+ rspec-mocks (~> 2.4.0)
28
+ rspec-core (2.4.0)
29
+ rspec-expectations (2.4.0)
30
+ diff-lcs (~> 1.1.2)
31
+ rspec-mocks (2.4.0)
32
+ thor (0.14.6)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ growl (>= 1.0.3)
39
+ guard-rspec (>= 0.1.9)
40
+ rb-fsevent (>= 0.3.9)
41
+ rspec (>= 2.4.0)
42
+ sum_sum!
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(/^spec\/(.*)_spec\.rb/) { "spec" }
3
+ watch(/^lib\/(.*)\.rb/) { "spec" } # { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(/^spec\/spec_helper\.rb/) { "spec" }
5
+ end
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ class SumSum < Hash
2
+ VERSION = "0.0.1"
3
+ end
data/lib/sum_sum.rb ADDED
@@ -0,0 +1,47 @@
1
+ class SumSum < Hash
2
+ def initialize(*args)
3
+ @parent = args.pop if args[-1].is_a?(self.class)
4
+ @name = args.shift
5
+ @args = args.compact.dup
6
+ @count = 0
7
+ super()
8
+ end
9
+
10
+ attr_reader :name, :args, :count, :parent
11
+
12
+ def add(hash, increase_by=1)
13
+ key = hash[name]
14
+ @count = @count + increase_by
15
+ unless bottom?
16
+ self[key] ||= SumSum.new(*args, self)
17
+ self[key].add(hash, increase_by)
18
+ end
19
+ self
20
+ end
21
+
22
+ def share
23
+ root? ? 1.0 : count/parent.count.to_f
24
+ end
25
+
26
+ def sort!
27
+ values.each(&:sort!) unless bottom?
28
+ to_a.tap do |array|
29
+ array.reverse!(&:count)
30
+ clear
31
+ array.each{|k, v| self[k] = v }
32
+ end
33
+ self
34
+ end
35
+
36
+ def root?
37
+ parent.nil?
38
+ end
39
+
40
+ def bottom?
41
+ name.nil?
42
+ end
43
+
44
+ def inspect
45
+ bottom? ? "#{count}" : "{#{name}:#{count} #{super.gsub(/^\{|\}$/, "")}}"
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ require 'guard'
2
+ require 'rspec'
3
+ require File.dirname(__FILE__) + '/../lib/sum_sum.rb'
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe SumSum do
4
+ context ".new" do
5
+ it "should raise no error with zero argument" do
6
+ lambda{ SumSum.new }.should_not raise_error(ArgumentError)
7
+ end
8
+
9
+ it "should raise no error with one argument" do
10
+ lambda{ SumSum.new(:x) }.should_not raise_error
11
+ end
12
+
13
+ it "should raise no error with multiple argument" do
14
+ lambda{ SumSum.new(:x, :y, :z) }.should_not raise_error
15
+ end
16
+ end
17
+
18
+ context "#add" do
19
+ let(:sum) { SumSum.new(:type, :name, :version) }
20
+
21
+ context "adding single hash" do
22
+ before do
23
+ sum.add({:type => :Browser, :name => :Firefox, :version => "3.6.0"})
24
+ end
25
+
26
+ context "#count" do
27
+ it "should return 1 on all levels" do
28
+ sum.count.should eql(1)
29
+ sum[:Browser].count.should eql(1)
30
+ sum[:Browser][:Firefox].count.should eql(1)
31
+ sum[:Browser][:Firefox]["3.6.0"].count.should eql(1)
32
+ end
33
+ end
34
+
35
+ context "#keys" do
36
+ it "should return correct keys on all levels" do
37
+ sum.keys.should eql([:Browser])
38
+ sum[:Browser].keys.should eql([:Firefox])
39
+ sum[:Browser][:Firefox].keys.should eql(["3.6.0"])
40
+ sum[:Browser][:Firefox]["3.6.0"].keys.should eql([])
41
+ end
42
+ end
43
+ end
44
+
45
+ context "adding multiple hashes" do
46
+ before do
47
+ sum.add({:type => :Crawler, :name => :GoogleBot, :version => "2.0"})
48
+ sum.add({:type => :Browser, :name => :Firefox, :version => "3.6.0"})
49
+ sum.add({:type => :Browser, :name => :Safari, :version => "4.0"})
50
+ sum.add({:type => :Browser, :name => :Safari, :version => "5.0"})
51
+ sum.add({:type => :Browser, :name => :Safari, :version => "5.0"})
52
+ end
53
+
54
+ context "#add" do
55
+ it "should return itself" do
56
+ sum.add({:type => :Crawler, :name => :GoogleBot, :version => "2.0"}).should eql(sum)
57
+ end
58
+
59
+ it "should add missing values as nil" do
60
+ sum.add({:type => :Crawler, :name => nil})
61
+ sum.add({:type => :Crawler})
62
+
63
+ sum[:Crawler].keys.should eql([:GoogleBot, nil])
64
+ sum[:Crawler][nil].count.should eql(2)
65
+ sum[:Crawler][nil].keys.should eql([nil])
66
+ sum[:Crawler][nil][nil].count.should eql(2)
67
+ end
68
+
69
+ it "should allow to add multiple counts at once" do
70
+ sum.add({:type => :Crawler, :name => :DuckDuckGo, :version => "1.0"}, 10)
71
+
72
+ sum[:Crawler].count.should eql(11)
73
+ sum[:Crawler][:DuckDuckGo].count.should eql(10)
74
+ sum[:Crawler][:DuckDuckGo]["1.0"].count.should eql(10)
75
+ end
76
+ end
77
+
78
+ context "#count" do
79
+ it "should return correct count on all levels" do
80
+ sum.count.should eql(5)
81
+
82
+ sum[:Browser].count.should eql(4)
83
+ sum[:Browser][:Firefox].count.should eql(1)
84
+ sum[:Browser][:Firefox]["3.6.0"].count.should eql(1)
85
+ sum[:Browser][:Safari].count.should eql(3)
86
+ sum[:Browser][:Safari]["5.0"].count.should eql(2)
87
+ sum[:Browser][:Safari]["4.0"].count.should eql(1)
88
+
89
+ sum[:Crawler].count.should eql(1)
90
+ sum[:Crawler][:GoogleBot].count.should eql(1)
91
+ sum[:Crawler][:GoogleBot]["2.0"].count.should eql(1)
92
+ end
93
+ end
94
+
95
+ context "#keys" do
96
+ it "should return correct keys on all levels" do
97
+ sum.keys.should eql([:Crawler, :Browser])
98
+ sum[:Browser].keys.should eql([:Firefox, :Safari])
99
+ sum[:Browser][:Firefox].keys.should eql(["3.6.0"])
100
+ sum[:Browser][:Firefox]["3.6.0"].keys.should eql([])
101
+ sum[:Browser][:Safari].keys.should eql(["4.0", "5.0"])
102
+ sum[:Browser][:Safari]["4.0"].keys.should eql([])
103
+ sum[:Browser][:Safari]["5.0"].keys.should eql([])
104
+ sum[:Crawler].keys.should eql([:GoogleBot])
105
+ sum[:Crawler][:GoogleBot].keys.should eql(["2.0"])
106
+ sum[:Crawler][:GoogleBot]["2.0"].keys.should eql([])
107
+ end
108
+ end
109
+
110
+ context "#sort" do
111
+ before do
112
+ sum.sort!
113
+ end
114
+
115
+ it "should sort by count" do
116
+ sum.keys.should eql([:Browser, :Crawler])
117
+ sum[:Browser].keys.should eql([:Safari, :Firefox])
118
+ sum[:Browser][:Safari].keys.should eql(["5.0", "4.0"])
119
+ end
120
+ end
121
+
122
+ context "#share" do
123
+ it "should return 1.0 on root" do
124
+ sum.share.should eql(1.0)
125
+ end
126
+
127
+ it "should return 1.0 on branch with single entry" do
128
+ sum[:Crawler][:GoogleBot].share.should eql(1.0)
129
+ end
130
+
131
+ it "should return 0.2 on branch with one out of five" do
132
+ sum[:Crawler].share.should eql(0.2)
133
+ end
134
+
135
+ it "should return 0.8 on branch with four out of five" do
136
+ sum[:Browser].share.should eql(0.8)
137
+ end
138
+
139
+ it "should return 0.25 on branch with one out of four" do
140
+ sum[:Browser][:Firefox].share.should eql(0.25)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
data/sum_sum.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sum_sum/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sum_sum"
7
+ s.version = SumSum::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Sebastian Munz"]
10
+ s.email = ["sebastian@yo.lk"]
11
+ s.homepage = "http://rubygems.org/gems/sum_sum"
12
+ s.summary = %q{SumSum allows you to generate simple reports on the count of values in hashes.}
13
+ s.description = %q{SumSum allows you to generate simple reports on the count of values in hashes.}
14
+
15
+ s.rubyforge_project = "sum_sum"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'rspec', '>= 2.4.0'
23
+ s.add_development_dependency 'guard-rspec', '>=0.1.9'
24
+ s.add_development_dependency 'growl', '>=1.0.3'
25
+ s.add_development_dependency 'rb-fsevent', '>=0.3.9'
26
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sum_sum
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Sebastian Munz
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-27 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 4
31
+ - 0
32
+ version: 2.4.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: guard-rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 1
46
+ - 9
47
+ version: 0.1.9
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: growl
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 0
61
+ - 3
62
+ version: 1.0.3
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rb-fsevent
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ - 3
76
+ - 9
77
+ version: 0.3.9
78
+ type: :development
79
+ version_requirements: *id004
80
+ description: SumSum allows you to generate simple reports on the count of values in hashes.
81
+ email:
82
+ - sebastian@yo.lk
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files: []
88
+
89
+ files:
90
+ - .gitignore
91
+ - .rvmrc
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - Guardfile
95
+ - Rakefile
96
+ - lib/sum_sum.rb
97
+ - lib/sum_sum/version.rb
98
+ - spec/spec_helper.rb
99
+ - spec/sum_sum_spec.rb
100
+ - sum_sum.gemspec
101
+ has_rdoc: true
102
+ homepage: http://rubygems.org/gems/sum_sum
103
+ licenses: []
104
+
105
+ post_install_message:
106
+ rdoc_options: []
107
+
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project: sum_sum
129
+ rubygems_version: 1.3.7
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: SumSum allows you to generate simple reports on the count of values in hashes.
133
+ test_files:
134
+ - spec/spec_helper.rb
135
+ - spec/sum_sum_spec.rb