meekster 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,151 @@
1
+ require File.expand_path("../lib/meekster", File.dirname(__FILE__))
2
+
3
+ describe "meekster" do
4
+
5
+ describe "simplest election" do
6
+ it "elects the candidate" do
7
+ c1 = Meekster::Candidate.new
8
+ c1.name = "Adam"
9
+ candidates = [c1]
10
+
11
+ b1 = Meekster::Ballot.new
12
+ b1.ranking = [c1]
13
+ ballots = [b1]
14
+
15
+ election = Meekster::Election.new
16
+ election.candidates = candidates
17
+ election.ballots = ballots
18
+ election.seats = 1
19
+
20
+ election.run!
21
+
22
+ c1.state.should == :elected
23
+ end
24
+ end
25
+
26
+ describe "wikipedia example STV election" do
27
+ before(:each) do
28
+ candidates = [
29
+ @oranges = Meekster::Candidate.new('Oranges'),
30
+ @pears = Meekster::Candidate.new('Pears'),
31
+ @chocolate = Meekster::Candidate.new('Chocolate'),
32
+ @strawberries = Meekster::Candidate.new('Stawberries'),
33
+ @sweets = Meekster::Candidate.new('Sweets')
34
+ ]
35
+
36
+ ballots = [
37
+ Meekster::Ballot.new([@oranges]),
38
+ Meekster::Ballot.new([@oranges]),
39
+ Meekster::Ballot.new([@oranges]),
40
+ Meekster::Ballot.new([@oranges]),
41
+ Meekster::Ballot.new([@pears, @oranges]),
42
+ Meekster::Ballot.new([@pears, @oranges]),
43
+ Meekster::Ballot.new([@chocolate, @strawberries]),
44
+ Meekster::Ballot.new([@chocolate, @strawberries]),
45
+ Meekster::Ballot.new([@chocolate, @strawberries]),
46
+ Meekster::Ballot.new([@chocolate, @strawberries]),
47
+ Meekster::Ballot.new([@chocolate, @strawberries]),
48
+ Meekster::Ballot.new([@chocolate, @strawberries]),
49
+ Meekster::Ballot.new([@chocolate, @strawberries]),
50
+ Meekster::Ballot.new([@chocolate, @strawberries]),
51
+ Meekster::Ballot.new([@chocolate, @sweets]),
52
+ Meekster::Ballot.new([@chocolate, @sweets]),
53
+ Meekster::Ballot.new([@chocolate, @sweets]),
54
+ Meekster::Ballot.new([@chocolate, @sweets]),
55
+ Meekster::Ballot.new([@strawberries]),
56
+ Meekster::Ballot.new([@sweets])
57
+ ]
58
+
59
+ election = Meekster::Election.new
60
+ election.candidates = candidates
61
+ election.ballots = ballots
62
+ election.seats = 3
63
+
64
+ election.run!
65
+ end
66
+
67
+ it "elects the correct candidates" do
68
+ @chocolate.state.should == :elected
69
+ @oranges.state.should == :elected
70
+ @strawberries.state.should == :elected
71
+ end
72
+
73
+ it "rejects the correct candidates" do
74
+ @pears.state.should == :defeated
75
+ @sweets.state.should == :defeated
76
+ end
77
+ end
78
+
79
+ # http://code.google.com/p/droop/wiki/Droop
80
+ describe "sample elections from Droop" do
81
+ describe "42" do
82
+ before(:all) do
83
+ @election = Meekster::Election.new(
84
+ :ballot_file => Meekster::BallotFile.new(
85
+ :filename => File.expand_path("ballot_files/42.blt", File.dirname(__FILE__))
86
+ )
87
+ )
88
+ @election.run!
89
+ end
90
+
91
+ it "elects the correct candidates" do
92
+ @election.candidates.find{|c| c.name == 'Castor'}.state.should == :elected
93
+ @election.candidates.find{|c| c.name == 'Castor'}.votes.should be_within(0.000000001).of(2.000000004)
94
+
95
+ @election.candidates.find{|c| c.name == 'Helen'}.state.should == :elected
96
+ @election.candidates.find{|c| c.name == 'Helen'}.votes.should be_within(0.000000001).of(2.000000000)
97
+ end
98
+
99
+ it "rejects the correct candidates" do
100
+ @election.candidates.find{|c| c.name == 'Pollux'}.state.should == :defeated
101
+ end
102
+
103
+ it "calculates votes for the rejected candidates correctly" do
104
+ pending('Need to fix final round') do
105
+ @election.candidates.find{|c| c.name == 'Pollux'}.votes.should be_within(0.000000001).of(0.000000000)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe "Anderston-City-2007" do
111
+ before(:all) do
112
+ @election = Meekster::Election.new(
113
+ :ballot_file => Meekster::BallotFile.new(
114
+ :filename => File.expand_path("ballot_files/Anderston-City-2007.blt", File.dirname(__FILE__))
115
+ )
116
+ )
117
+ @election.run!
118
+ end
119
+
120
+ it "elects the correct candidates" do
121
+ @election.candidates.find{|c| c.name == 'Nina Baker'}.state.should == :elected
122
+ @election.candidates.find{|c| c.name == 'Nina Baker'}.votes.should be_within(0.00001).of(1298.307340419)
123
+
124
+ @election.candidates.find{|c| c.name == 'Philip Braat'}.state.should == :elected
125
+ @election.candidates.find{|c| c.name == 'Philip Braat'}.votes.should be_within(0.00001).of(1297.105615751)
126
+
127
+ @election.candidates.find{|c| c.name == 'Craig MacKay'}.state.should == :elected
128
+ @election.candidates.find{|c| c.name == 'Craig MacKay'}.votes.should be_within(0.00001).of(1280.501790024)
129
+
130
+ @election.candidates.find{|c| c.name == 'Gordon Matheson'}.state.should == :elected
131
+ @election.candidates.find{|c| c.name == 'Gordon Matheson'}.votes.should be_within(0.00001).of(1325.225745098)
132
+ end
133
+
134
+ it "rejects the correct candidates" do
135
+ ['Erin Boyle', 'Dave Holladay', 'Akhtar Khan', 'Ann Laird', 'Peter Murray'].each do |name|
136
+ @election.candidates.find{|c| c.name == name}.state.should == :defeated
137
+ end
138
+ end
139
+
140
+ it "calculates votes for the rejected candidates correctly" do
141
+ pending('Need to fix final round')
142
+ end
143
+ end
144
+ end
145
+
146
+ it "calculates the final quota"
147
+ it "calculates the final number of votes"
148
+ it "calculates the final residual"
149
+ it "calculates the final surplus"
150
+
151
+ end
@@ -0,0 +1,22 @@
1
+ require './lib/meekster/round'
2
+ require 'bigdecimal'
3
+
4
+ describe Meekster::Round do
5
+
6
+ describe ".round_up_to_nine_decimal_places" do
7
+ it "rounds to the same value when tenth and later decimal places are zero" do
8
+ Meekster::Round.round_up_to_nine_decimal_places(BigDecimal('1.1234567890')).should == BigDecimal('1.123456789')
9
+ end
10
+
11
+ it "rounds up when tenth decimal place is present" do
12
+ Meekster::Round.round_up_to_nine_decimal_places(BigDecimal('1.2222222221')).should == BigDecimal('1.2222222230')
13
+ end
14
+ end
15
+
16
+ describe ".truncate_to_nine_decimal_places" do
17
+ it "removes tenth decimal and more" do
18
+ Meekster::Round.truncate_to_nine_decimal_places(BigDecimal('1.3333333337777')).should == BigDecimal('1.333333333')
19
+ end
20
+ end
21
+
22
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meekster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Mear
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 2.9.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 2.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.2
41
+ description: Meekster implements a Meek Single Transferable Vote (STV) voting system,
42
+ as described in the Proportional Representation Foundation's Reference Meek Rule.
43
+ email: chris@feedmechocolate.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - README.md
51
+ - Rakefile
52
+ - lib/meekster.rb
53
+ - lib/meekster/ballot.rb
54
+ - lib/meekster/ballot_file.rb
55
+ - lib/meekster/candidate.rb
56
+ - lib/meekster/election.rb
57
+ - lib/meekster/round.rb
58
+ - lib/meekster/version.rb
59
+ - meekster.gemspec
60
+ - spec/ballot_file_spec.rb
61
+ - spec/ballot_files/42.blt
62
+ - spec/ballot_files/Anderston-City-2007.blt
63
+ - spec/meekster_spec.rb
64
+ - spec/round_spec.rb
65
+ homepage: https://github.com/chrismear/meekster
66
+ licenses: []
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.0.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: An implementation of the Meek STV election voting system.
88
+ test_files:
89
+ - spec/ballot_file_spec.rb
90
+ - spec/ballot_files/42.blt
91
+ - spec/ballot_files/Anderston-City-2007.blt
92
+ - spec/meekster_spec.rb
93
+ - spec/round_spec.rb