bf_crowdfund 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16ada801d78740d7aca241cbd6fac6f517fe95b2
4
+ data.tar.gz: 48e5d7eaf81ff1a41c3aac21b2e542d12487fe2c
5
+ SHA512:
6
+ metadata.gz: a33a9858350fd88f421107e2e31f260c2735c64a855f7d771dea4fdfc5848351131a5f5a97d161e241a7372d4d37c24f065e5fac82cd7e9fe449b596ee2aff3c
7
+ data.tar.gz: da812bf8c162a8b8eb1c3f66c2e598a2ba7a36be0353044f8d24a2aca8261e8f870a0e4f325475c21b7d046697117091910f05c6f61fa5d0227861cee382aa1a
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+
2
+ Copyright (C) <2014> <BFITC, LLC>
3
+
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,4 @@
1
+ crowdfund
2
+ =========
3
+
4
+ Track funding, funding projects, and status of funding efforts.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/crowdfund/project'
4
+ require_relative '../lib/crowdfund/funding'
5
+
6
+ vc_funds = Crowdfund::Funding.new("VC-Friendly Start-up Projects")
7
+ default_project_file = File.join(File.dirname(__FILE__), 'projects.csv')
8
+ vc_funds.load_projects(ARGV.shift || default_project_file)
9
+
10
+ loop do
11
+ puts "How many funding rounds ('quit' to exit)"
12
+ answer = gets.chomp.downcase
13
+ case answer
14
+ when /^\d+$/
15
+ vc_funds.request_funding(answer.to_i)
16
+ when 'quit', 'exit', 'q', 'x', 'bye'
17
+ vc_funds.print_stats
18
+ break
19
+ else
20
+ puts "Please enter a number or 'quit'"
21
+ end
22
+ end
23
+
24
+ vc_funds.save_under_funded_projects
@@ -0,0 +1,3 @@
1
+ csv1,0,100
2
+ csv2,50,500
3
+ csv3,100,1000
@@ -0,0 +1,5 @@
1
+ mozart concert,900,9000
2
+ beethoven concert,50,5000
3
+ sibelius concert, 10,10000
4
+ bartok concert,5000,6000
5
+ christmas concert,9000,8000
@@ -0,0 +1,6 @@
1
+ require_relative 'project'
2
+
3
+ module Crowdfund
4
+ class Endowment < Project
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ module Crowdfund
2
+ module Fundable
3
+ def add(donation=25)
4
+ @funds = @funds + donation
5
+ puts "Project #{@name} got more funds!"
6
+ end
7
+
8
+
9
+ def subtract(expense=15)
10
+ @funds = @funds - expense
11
+ puts "Project #{@name} spent too much money! DARN!"
12
+ end
13
+
14
+ def funds_still_needed
15
+ @goal - funding_pledged
16
+ end
17
+
18
+ def fully_funded?
19
+ if funds_still_needed <=0
20
+ true
21
+ else
22
+ false
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,107 @@
1
+ require_relative 'project'
2
+ require_relative 'funding_round'
3
+ require 'csv'
4
+
5
+ module Crowdfund
6
+ class Funding
7
+ attr_reader :title
8
+
9
+ def initialize(title)
10
+ @title = title
11
+ @projects = []
12
+ end
13
+
14
+ def load_projects(from_file)
15
+ CSV.foreach(from_file) do |row|
16
+ project = Project.new(row[0], row[1].to_i, row[2].to_i)
17
+ add_project(project)
18
+ end
19
+ end
20
+
21
+ def add_project(a_project)
22
+ @projects << a_project
23
+ puts "#{a_project.name} was added to #{@title}."
24
+ end
25
+
26
+ def fund_fun(campaigns)
27
+ @projects.each do |project|
28
+ puts project
29
+ end
30
+
31
+ 1.upto(campaigns) do |campaign|
32
+ puts "\nCampaign: #{campaign}:"
33
+ @projects.each do |project|
34
+ FundingRound.spend_or_receive(project)
35
+ end
36
+ end
37
+ end
38
+
39
+ def request_funding(campaigns)
40
+ fund_fun(campaigns)
41
+ puts "\n\nProjects:"
42
+ @projects.each do |project|
43
+ puts project
44
+ end
45
+ end
46
+
47
+ def funding_partition
48
+ @fully_funded, @under_funded = @projects.partition {|project| project.fully_funded?}
49
+ end
50
+
51
+ def funding_status(project)
52
+ formatted_name = project.name.ljust(20,' ')
53
+ "#{formatted_name} \tCurrent Funds: $#{project.funding_pledged} \tStill to Raise: $#{project.funds_still_needed}"
54
+ end
55
+
56
+ def save_under_funded_projects(to_file = "needs_funds.txt")
57
+ funding_partition
58
+ sorted_projects = @under_funded.sort
59
+ File.open(to_file, "w") do |file|
60
+ file.puts "\n#{@under_funded.size} #{@title} projects needing funds:"
61
+ sorted_projects.each do |project|
62
+ file.puts funding_status(project)
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ def print_stats
69
+ puts "\n#{@title} Statistics:"
70
+ funding_partition
71
+ puts "\n#{@fully_funded.size} fully funded projects:"
72
+
73
+ puts "\n#{@under_funded.size} under funded projects:"
74
+ puts "\nPrioritized Projects:"
75
+ sorted_projects = @under_funded.sort
76
+ sorted_projects.each do |project|
77
+ puts funding_status(project)
78
+ end
79
+ @projects.sort.each do |project|
80
+ puts "\nProject #{project.name}'s pledges:"
81
+ project.each_pledge_level do |pledge|
82
+ puts "#{pledge.amount} in #{pledge.name} pledges"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ if __FILE__ == $0
90
+ puts "=================================" "\n"
91
+ puts "Exercise 10. Fundrequest Class:"
92
+
93
+ project1 = Project.new("lmn", 500, 3000)
94
+ puts project1
95
+ project2 = Project.new("xyz", 25, 75)
96
+ puts project2
97
+ project3 = Project.new("abc", 4500, 10000)
98
+ puts project3
99
+ project4 = Project.new("def", 5, 50)
100
+ puts project4
101
+ vc_funds = Funding.new("VC-Friendly Start-up Projects")
102
+ vc_funds.add_project(project1)
103
+ vc_funds.add_project(project2)
104
+ vc_funds.add_project(project3)
105
+ vc_funds.add_project(project4)
106
+ vc_funds.request_funding(2)
107
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'pledge_pool'
2
+ require_relative 'project'
3
+
4
+ module Crowdfund
5
+ module FundingRound
6
+ def self.roll_die
7
+ rand(1..6)
8
+ end
9
+
10
+ def self.spend_or_receive(project)
11
+ number_rolled = roll_die
12
+ if number_rolled.even?
13
+ project.add
14
+ else
15
+ project.subtract
16
+ end
17
+ pledge = PledgePool.random
18
+ project.received_pledge(pledge)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'project'
2
+
3
+ module Crowdfund
4
+ class GrantProject < Project
5
+ def subtract(expense=0)
6
+ @funds = @funds
7
+ puts "Project #{@name} is a grant project. Money cannot be removed!"
8
+ end
9
+ end
10
+ end
11
+
12
+ if __FILE__ == $0
13
+ puts "=================================" "\n"
14
+ puts "Grant Project Class:"
15
+ gproject1 = GrantProject.new("glmn", 5000, 6000)
16
+ puts gproject1
17
+
18
+ gproject2 = GrantProject.new("gxyz", 25000, 25000)
19
+ puts gproject2
20
+
21
+ gproject3 = GrantProject.new("gabc", 45000, 45000)
22
+ puts gproject3
23
+ gproject4 = GrantProject.new("gdef", 500, 500)
24
+ puts gproject4
25
+ gproject4.subtract
26
+ puts gproject4
27
+ end
28
+
@@ -0,0 +1,36 @@
1
+ require_relative 'project'
2
+
3
+ module Crowdfund
4
+ class MatchedProject < Project
5
+ def add(donation=25)
6
+ if @funds >= @goal/2
7
+ @funds = @funds + (donation * 2)
8
+ puts "Project #{@name} got matched funds!"
9
+ else
10
+ @funds = @funds + donation
11
+ puts "Project #{@name} got more funds!"
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ if __FILE__ == $0
18
+ puts "=================================" "\n"
19
+ puts "Matched Project Class:"
20
+ gproject1 = MatchedProject.new("mlmn", 5000, 6000)
21
+ puts gproject1
22
+
23
+ gproject2 = MatchedProject.new("mxyz", 25000, 25000)
24
+ puts gproject2
25
+
26
+ gproject3 = MatchedProject.new("mabc", 45000, 45000)
27
+ puts gproject3
28
+ gproject4 = MatchedProject.new("mdef", 500, 500)
29
+ puts gproject4
30
+ gproject4.subtract(275)
31
+ puts gproject4
32
+ gproject4.add(25)
33
+ puts gproject4
34
+ gproject4.add(25)
35
+ puts gproject4
36
+ end
@@ -0,0 +1,17 @@
1
+ module Crowdfund
2
+
3
+ Pledge = Struct.new(:name, :amount)
4
+
5
+ module PledgePool
6
+ PLEDGES = [
7
+ Pledge.new(:bronze, 50),
8
+ Pledge.new(:silver, 75),
9
+ Pledge.new(:gold, 100),
10
+ Pledge.new(:platinum, 500)
11
+ ]
12
+
13
+ def self.random
14
+ PLEDGES.sample
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'fundable'
2
+
3
+ module Crowdfund
4
+ class Project
5
+ include Fundable
6
+
7
+ attr_reader :funds, :goal
8
+ attr_accessor :name
9
+ def initialize(name, funds=0, goal=0)
10
+ @name = name.upcase
11
+ @funds = funds
12
+ @goal = goal
13
+ @pledges = Hash.new(0)
14
+ end
15
+
16
+ def received_pledge(pledge)
17
+ @pledges[pledge.name] += pledge.amount
18
+
19
+ puts "Project #{@name} received a #{pledge.name} pledge worth $#{pledge.amount}."
20
+ puts "Project #{name}'s pledges: #{@pledges}"
21
+ end
22
+
23
+ def pledge_amounts
24
+ @pledges.values.reduce(0, :+)
25
+ end
26
+
27
+ def each_pledge_level
28
+ @pledges.each do |name, amount|
29
+ yield Pledge.new(name, amount)
30
+ end
31
+ end
32
+
33
+ def funding_pledged
34
+ @funds + pledge_amounts
35
+ end
36
+
37
+ def name=(new_name)
38
+ @name=new_name.upcase
39
+ end
40
+
41
+ def <=>(other_project)
42
+ other_project.funds_still_needed <=> funds_still_needed
43
+ end
44
+
45
+ def to_s
46
+ "Project #{@name} has $#{funding_pledged} in funds towards a goal of $#{@goal} with $#{funds_still_needed} to be raised."
47
+ end
48
+ end
49
+ end
50
+
51
+ if __FILE__ == $0
52
+ puts "=================================" "\n"
53
+ puts "Exercise 10. Project Class:"
54
+ project1 = Project.new("lmn", 500, 3000)
55
+ puts project1
56
+
57
+ project2 = Project.new("xyz", 25, 75)
58
+ puts project2
59
+
60
+ project3 = Project.new("abc", 4500, 10000)
61
+ puts project3
62
+ project4 = Project.new("def", 5, 50)
63
+ puts project4
64
+ end
@@ -0,0 +1,6 @@
1
+ require 'crowdfund/endowment'
2
+
3
+ module Crowdfund
4
+ describe Endowment do
5
+ end
6
+ end
@@ -0,0 +1,38 @@
1
+ require 'crowdfund/funding'
2
+ require 'crowdfund/project'
3
+
4
+ module Crowdfund
5
+ describe Funding do
6
+ before do
7
+ @vc_funds = Funding.new("VC-Friendly Start-up Projects")
8
+ @initial_funds = 500
9
+ @goal = 10000
10
+
11
+
12
+ @project = Project.new("stu", @initial_funds, @goal)
13
+ @vc_funds.add_project(@project)
14
+ end
15
+
16
+ it "adds funds to a project if an even number is rolled" do
17
+ FundingRound.stub(:roll_die).and_return(4)
18
+
19
+ @vc_funds.fund_fun(3)
20
+ @project.funds.should == @initial_funds + 25 *3
21
+ end
22
+
23
+ it "subtracts funds from a project if an odd number is rolled" do
24
+ FundingRound.stub(:roll_die).and_return(3)
25
+
26
+ @vc_funds.fund_fun(2)
27
+ @project.funds.should == @initial_funds - 15 * 2
28
+ end
29
+
30
+ it "adds funds to a project if a pledge is received" do
31
+
32
+ @project.received_pledge(Pledge.new(:gold,100))
33
+
34
+ @project.funding_pledged.should == @initial_funds + 100
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,17 @@
1
+ require 'crowdfund/grant_project'
2
+
3
+ module Crowdfund
4
+ describe GrantProject do
5
+ before do
6
+ @current_funding = 10000
7
+ @initial_target = 100000
8
+ @gproject = GrantProject.new("gabc", @current_funding, @initial_target)
9
+ end
10
+
11
+ it "cannot have funds removed" do
12
+ @gproject.subtract
13
+
14
+ @gproject.funds.should == @current_funding
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ require 'crowdfund/matched_project'
2
+
3
+ module Crowdfund
4
+ describe MatchedProject do
5
+ before do
6
+ @current_funding = 10000
7
+ @initial_target = 100000
8
+ @mproject = MatchedProject.new("mdef", @current_funding, @initial_target)
9
+ end
10
+
11
+ it "doesn't match until half the goal is reached" do
12
+ @mproject.add(25)
13
+
14
+ @mproject.funds.should == @current_funding + 25
15
+
16
+ @mproject = MatchedProject.new("mdef", (@initial_target/2 - 25))
17
+
18
+ @mproject.funds.should == (@initial_target/2 - 25)
19
+
20
+ @mproject.add(25)
21
+
22
+ @mproject.funds.should == (@initial_target/2 + 25)
23
+ end
24
+
25
+
26
+
27
+ it "matches donations after half the goal is reached" do
28
+ @mproject.add((@initial_target/2) - @current_funding)
29
+ @mproject.add(25)
30
+
31
+ @mproject.funds.should == @initial_target/2 + 50
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,45 @@
1
+ require 'crowdfund/pledge_pool'
2
+
3
+ module Crowdfund
4
+ describe Pledge do
5
+ before do
6
+ @pledge = Pledge.new(:bronze, 50)
7
+ end
8
+
9
+ it "has a name attribute" do
10
+ @pledge.name.should == :bronze
11
+ end
12
+
13
+ it "has an amount attribute" do
14
+ @pledge.amount.should == 50
15
+ end
16
+ end
17
+
18
+ describe PledgePool do
19
+ it "has four pledge levels" do
20
+ PledgePool::PLEDGES.size.should == 4
21
+ end
22
+
23
+ it "has a bronze level pledge that is worth $50" do
24
+ PledgePool::PLEDGES[0].should == Pledge.new(:bronze, 50)
25
+ end
26
+
27
+ it "has a silver level pledge that is worth $75" do
28
+ PledgePool::PLEDGES[1].should == Pledge.new(:silver, 75)
29
+ end
30
+
31
+ it "has a gold level pledge that is worth $100" do
32
+ PledgePool::PLEDGES[2].should == Pledge.new(:gold, 100)
33
+ end
34
+
35
+ it "has a platinum level pledge that is worth $500" do
36
+ PledgePool::PLEDGES[3].should == Pledge.new(:platinum, 500)
37
+ end
38
+
39
+ it "returns a random pledge" do
40
+ pledge = PledgePool.random
41
+
42
+ PledgePool::PLEDGES.should include(pledge)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,144 @@
1
+ require 'crowdfund/project'
2
+ require 'crowdfund/pledge_pool'
3
+ require 'csv'
4
+
5
+ module Crowdfund
6
+ describe Project do
7
+
8
+ before do
9
+ $stdout = StringIO.new
10
+ @current_funding = 100
11
+ @initial_target = 1000
12
+ @project = Project.new("abc", @current_funding, @initial_target)
13
+ end
14
+
15
+ it "has an initial target funding amount" do
16
+ @project.goal.should == @initial_target
17
+ end
18
+
19
+ it "computes the total funding outstanding as the target funding amount minus the funding amount" do
20
+ @project.funds_still_needed == @initial_target - @current_funding
21
+ end
22
+
23
+ it "increases funds by 25 when funds are added" do
24
+ @project.add
25
+
26
+ @project.funds.should == @current_funding + 25
27
+ end
28
+
29
+ it "decreases funds by 15 when funds are removed" do
30
+ @project.subtract
31
+
32
+ @project.funds.should == @current_funding - 15
33
+ end
34
+
35
+ context "Project created with a default funding amount" do
36
+ before do
37
+ @project = Project.new("def")
38
+ end
39
+
40
+ it "has a default value of 0 for funding amount" do
41
+ @project.funds.should == 0
42
+ end
43
+ end
44
+
45
+ context "Project created with funding greater than the goal" do
46
+ before do
47
+ $stdout = StringIO.new
48
+ @current_funding = 1001
49
+ @initial_target = 1000
50
+ @project = Project.new("abc", @current_funding, @initial_target)
51
+ end
52
+
53
+ it "has more funds than the goal" do
54
+ @project.funds.should > @project.goal
55
+ end
56
+
57
+ it "is fully funded" do
58
+ @project.fully_funded?.should == true
59
+ end
60
+ end
61
+
62
+ context "Project created with funding equal to the goal" do
63
+ before do
64
+ $stdout = StringIO.new
65
+ @current_funding = 1000
66
+ @initial_target = 1000
67
+ @project = Project.new("abc", @current_funding, @initial_target)
68
+ end
69
+
70
+ it "funds have met the goal" do
71
+ @project.funds.should == @project.goal
72
+ end
73
+
74
+ it "is fully funded" do
75
+ @project.fully_funded?.should == true
76
+ end
77
+ end
78
+
79
+ context "Project created with funding less than the goal" do
80
+ before do
81
+ $stdout = StringIO.new
82
+ @current_funding = 999
83
+ @initial_target = 1000
84
+ @project = Project.new("abc", @current_funding, @initial_target)
85
+ end
86
+
87
+ it "has not met the goal" do
88
+ @project.funds.should < @project.goal
89
+ end
90
+
91
+ it "is not fully funded yet" do
92
+ @project.fully_funded?.should == false
93
+ end
94
+ end
95
+
96
+ it "computes the sum of all pledges" do
97
+ @project.pledge_amounts.should == 0
98
+
99
+ @project.received_pledge(Pledge.new(:bronze,50))
100
+
101
+ @project.pledge_amounts.should == 50
102
+
103
+ @project.received_pledge(Pledge.new(:platinum,500))
104
+
105
+ @project.pledge_amounts.should == 550
106
+
107
+ @project.received_pledge(Pledge.new(:bronze,50))
108
+
109
+ @project.pledge_amounts.should == 600
110
+ end
111
+
112
+ it "yields the total pledges for each pledge level" do
113
+ @project.received_pledge(Pledge.new(:bronze, 50))
114
+ @project.received_pledge(Pledge.new(:bronze, 50))
115
+ @project.received_pledge(Pledge.new(:silver, 75))
116
+ @project.received_pledge(Pledge.new(:silver, 75))
117
+ @project.received_pledge(Pledge.new(:gold, 100))
118
+ @project.received_pledge(Pledge.new(:gold, 100))
119
+ @project.received_pledge(Pledge.new(:platinum, 500))
120
+ @project.received_pledge(Pledge.new(:platinum, 500))
121
+
122
+ yielded = []
123
+ @project.each_pledge_level do |pledge|
124
+ yielded << pledge
125
+ end
126
+
127
+ yielded.should == [
128
+ Pledge.new(:bronze, 100),
129
+ Pledge.new(:silver, 150),
130
+ Pledge.new(:gold, 200),
131
+ Pledge.new(:platinum, 1000)
132
+ ]
133
+ end
134
+
135
+ it "can be created from a CSV string" do
136
+ project = Project.new("csv", 1000, 100)
137
+
138
+ project.name.should == "CSV"
139
+ project.funds.should == 1000
140
+ project.goal.should == 100
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,144 @@
1
+ require 'crowdfund/project'
2
+ require 'crowdfund/pledge_pool'
3
+ require 'csv'
4
+
5
+ module Crowdfund
6
+ describe Project do
7
+
8
+ before do
9
+ $stdout = StringIO.new
10
+ @current_funding = 100
11
+ @initial_target = 1000
12
+ @project = Project.new("abc", @current_funding, @initial_target)
13
+ end
14
+
15
+ it "has an initial target funding amount" do
16
+ @project.goal.should == @initial_target
17
+ end
18
+
19
+ it "computes the total funding outstanding as the target funding amount minus the funding amount" do
20
+ @project.funds_still_needed == @initial_target - @current_funding
21
+ end
22
+
23
+ it "increases funds by 25 when funds are added" do
24
+ @project.add
25
+
26
+ @project.funds.should == @current_funding + 25
27
+ end
28
+
29
+ it "decreases funds by 15 when funds are removed" do
30
+ @project.subtract
31
+
32
+ @project.funds.should == @current_funding - 15
33
+ end
34
+
35
+ context "Project created with a default funding amount" do
36
+ before do
37
+ @project = Project.new("def")
38
+ end
39
+
40
+ it "has a default value of 0 for funding amount" do
41
+ @project.funds.should == 0
42
+ end
43
+ end
44
+
45
+ context "Project created with funding greater than the goal" do
46
+ before do
47
+ $stdout = StringIO.new
48
+ @current_funding = 1001
49
+ @initial_target = 1000
50
+ @project = Project.new("abc", @current_funding, @initial_target)
51
+ end
52
+
53
+ it "has more funds than the goal" do
54
+ @project.funds.should > @project.goal
55
+ end
56
+
57
+ it "is fully funded" do
58
+ @project.fully_funded?.should == true
59
+ end
60
+ end
61
+
62
+ context "Project created with funding equal to the goal" do
63
+ before do
64
+ $stdout = StringIO.new
65
+ @current_funding = 1000
66
+ @initial_target = 1000
67
+ @project = Project.new("abc", @current_funding, @initial_target)
68
+ end
69
+
70
+ it "funds have met the goal" do
71
+ @project.funds.should == @project.goal
72
+ end
73
+
74
+ it "is fully funded" do
75
+ @project.fully_funded?.should == true
76
+ end
77
+ end
78
+
79
+ context "Project created with funding less than the goal" do
80
+ before do
81
+ $stdout = StringIO.new
82
+ @current_funding = 999
83
+ @initial_target = 1000
84
+ @project = Project.new("abc", @current_funding, @initial_target)
85
+ end
86
+
87
+ it "has not met the goal" do
88
+ @project.funds.should < @project.goal
89
+ end
90
+
91
+ it "is not fully funded yet" do
92
+ @project.fully_funded?.should == false
93
+ end
94
+ end
95
+
96
+ it "computes the sum of all pledges" do
97
+ @project.pledge_amounts.should == 0
98
+
99
+ @project.received_pledge(Pledge.new(:bronze,50))
100
+
101
+ @project.pledge_amounts.should == 50
102
+
103
+ @project.received_pledge(Pledge.new(:platinum,500))
104
+
105
+ @project.pledge_amounts.should == 550
106
+
107
+ @project.received_pledge(Pledge.new(:bronze,50))
108
+
109
+ @project.pledge_amounts.should == 600
110
+ end
111
+
112
+ it "yields the total pledges for each pledge level" do
113
+ @project.received_pledge(Pledge.new(:bronze, 50))
114
+ @project.received_pledge(Pledge.new(:bronze, 50))
115
+ @project.received_pledge(Pledge.new(:silver, 75))
116
+ @project.received_pledge(Pledge.new(:silver, 75))
117
+ @project.received_pledge(Pledge.new(:gold, 100))
118
+ @project.received_pledge(Pledge.new(:gold, 100))
119
+ @project.received_pledge(Pledge.new(:platinum, 500))
120
+ @project.received_pledge(Pledge.new(:platinum, 500))
121
+
122
+ yielded = []
123
+ @project.each_pledge_level do |pledge|
124
+ yielded << pledge
125
+ end
126
+
127
+ yielded.should == [
128
+ Pledge.new(:bronze, 100),
129
+ Pledge.new(:silver, 150),
130
+ Pledge.new(:gold, 200),
131
+ Pledge.new(:platinum, 1000)
132
+ ]
133
+ end
134
+
135
+ it "can be created from a CSV string" do
136
+ project = Crowdfund::Project.new("csv", 1000, 100)
137
+
138
+ project.name.should == "CSV"
139
+ project.funds.should == 1000
140
+ project.goal.should == 100
141
+ end
142
+
143
+ end
144
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bf_crowdfund
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Bob Fried
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-06 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: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: |-
28
+ crowdfund
29
+ =========
30
+
31
+ Track funding, funding projects, and status of funding efforts.
32
+ email: bobfried@centurylink.net
33
+ executables:
34
+ - crowdfund
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - LICENSE
39
+ - README
40
+ - bin/crowdfund
41
+ - bin/projects.csv
42
+ - bin/top_projects.csv
43
+ - lib/crowdfund/endowment.rb
44
+ - lib/crowdfund/fundable.rb
45
+ - lib/crowdfund/funding.rb
46
+ - lib/crowdfund/funding_round.rb
47
+ - lib/crowdfund/grant_project.rb
48
+ - lib/crowdfund/matched_project.rb
49
+ - lib/crowdfund/pledge_pool.rb
50
+ - lib/crowdfund/project.rb
51
+ - spec/crowdfund/endowment_spec.rb
52
+ - spec/crowdfund/funding_spec.rb
53
+ - spec/crowdfund/grant_project_spec.rb
54
+ - spec/crowdfund/matched_project_spec.rb
55
+ - spec/crowdfund/pledge_pool_spec.rb
56
+ - spec/crowdfund/project_spec.rb
57
+ - spec/project_spec.rb
58
+ homepage: http://pragmaticstudio.com
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '1.9'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.2.2
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Tracks funding
82
+ test_files:
83
+ - spec/project_spec.rb
84
+ - spec/crowdfund/matched_project_spec.rb
85
+ - spec/crowdfund/project_spec.rb
86
+ - spec/crowdfund/pledge_pool_spec.rb
87
+ - spec/crowdfund/funding_spec.rb
88
+ - spec/crowdfund/endowment_spec.rb
89
+ - spec/crowdfund/grant_project_spec.rb