crowdfund_sergio_silva 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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README +6 -0
- data/bin/crowdfund +50 -0
- data/bin/projects.csv +3 -0
- data/bin/results.txt +3 -0
- data/lib/crowdfund/die.rb +20 -0
- data/lib/crowdfund/fundable.rb +23 -0
- data/lib/crowdfund/funding_round.rb +23 -0
- data/lib/crowdfund/fundrequest.rb +114 -0
- data/lib/crowdfund/grant_project.rb +19 -0
- data/lib/crowdfund/matching_project.rb +31 -0
- data/lib/crowdfund/pledge_pool.rb +22 -0
- data/lib/crowdfund/project.rb +54 -0
- data/spec/crowdfund/fundrequest_spec.rb +42 -0
- data/spec/crowdfund/grant_project_spec.rb +20 -0
- data/spec/crowdfund/matching_project_spec.rb +30 -0
- data/spec/crowdfund/pledge_pool_spec.rb +45 -0
- data/spec/crowdfund/project_spec.rb +100 -0
- metadata +81 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f504e5608564e2e76a9b02c6a93b438e6fed955a
|
|
4
|
+
data.tar.gz: ebb8b1ea04b6891bcb8f9cc98aefddbe6759f768
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fd3dd8a2773fd9bbdd4136f66b0835b4913f6df03795c941dbe35e2924c757e222c2f2b566e3765d9a8d0c842ed097d8f268889498068c89bb79a418af085526
|
|
7
|
+
data.tar.gz: d5bc9de9151d96a9d3172e27f370532788d9b62b4f37c0b55deb6ea013657d386a599685c8eb68b6f97c256cebf3efa8d870e0170e9076b7fdf73f974cd15eb6
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Copyright (c) 2012 The Pragmatic Studio
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
- You may not use this Software in other training contexts.
|
|
11
|
+
|
|
12
|
+
- The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README
ADDED
data/bin/crowdfund
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/crowdfund/project'
|
|
4
|
+
require_relative '../lib/crowdfund/fundrequest'
|
|
5
|
+
require_relative '../lib/crowdfund/grant_project'
|
|
6
|
+
require_relative '../lib/crowdfund/matching_project'
|
|
7
|
+
|
|
8
|
+
#create a fundrequest
|
|
9
|
+
projects = Crowdfund::FundRequest.new("Ruby course Crowdfunding App")
|
|
10
|
+
puts "#{ projects.title }\n\n"
|
|
11
|
+
|
|
12
|
+
default_player_file = File.join(File.dirname(__FILE__), 'projects.csv')
|
|
13
|
+
projects.load_projects(ARGV.shift || default_player_file)
|
|
14
|
+
|
|
15
|
+
#Create other projects
|
|
16
|
+
project4 = Crowdfund::MatchingProject.new("Match", 200)
|
|
17
|
+
project5 = Crowdfund::GrantProject.new("Grant", 1_000, 300)
|
|
18
|
+
|
|
19
|
+
#Adds these projects
|
|
20
|
+
projects.add_project(project4)
|
|
21
|
+
projects.add_project(project5)
|
|
22
|
+
|
|
23
|
+
#Running
|
|
24
|
+
loop do
|
|
25
|
+
puts "\nHow many rounds of funding? ('quit' to exit)"
|
|
26
|
+
answer = gets.chomp.downcase
|
|
27
|
+
case answer
|
|
28
|
+
when /^\d+$/
|
|
29
|
+
projects.request_funding(answer.to_i)
|
|
30
|
+
when 'quit', 'exit'
|
|
31
|
+
projects.print_stats
|
|
32
|
+
break
|
|
33
|
+
else
|
|
34
|
+
puts "Please enter a number or 'quit'"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#project1 = Crowdfund::Project.new("ABC", 1_000, 500)
|
|
39
|
+
#project2 = Crowdfund::Project.new("LMN", 500, 3_000)
|
|
40
|
+
#project3 = Crowdfund::Project.new("XYZ", 25, 75)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
#projects.add_project(project1)
|
|
44
|
+
#projects.add_project(project2)
|
|
45
|
+
#projects.add_project(project3)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
#projects.request_funding(4)
|
|
49
|
+
|
|
50
|
+
#projects.print_stats
|
data/bin/projects.csv
ADDED
data/bin/results.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Crowdfund
|
|
2
|
+
module Fundable
|
|
3
|
+
|
|
4
|
+
def remove_funds
|
|
5
|
+
@funding -= 15
|
|
6
|
+
puts "#{ @name } lost some funds!"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def add_funds
|
|
10
|
+
@funding += 25
|
|
11
|
+
puts "#{ @name } got more funds!"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def total_funding_outstanding
|
|
15
|
+
@target - total_funds
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def fully_funded?
|
|
19
|
+
total_funding_outstanding <= 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'die'
|
|
2
|
+
require_relative 'project'
|
|
3
|
+
|
|
4
|
+
module Crowdfund
|
|
5
|
+
module FundingRound
|
|
6
|
+
|
|
7
|
+
@die = Die.new
|
|
8
|
+
|
|
9
|
+
def self.round(project)
|
|
10
|
+
number_rolled = @die.roll
|
|
11
|
+
|
|
12
|
+
if number_rolled.odd?
|
|
13
|
+
project.remove_funds
|
|
14
|
+
else
|
|
15
|
+
project.add_funds
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
pledge = PledgePool.random
|
|
19
|
+
project.received_pledge(pledge)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
require_relative 'die'
|
|
3
|
+
require_relative 'funding_round'
|
|
4
|
+
require_relative 'pledge_pool'
|
|
5
|
+
|
|
6
|
+
module Crowdfund
|
|
7
|
+
class FundRequest
|
|
8
|
+
|
|
9
|
+
attr_reader :title
|
|
10
|
+
|
|
11
|
+
def initialize(title)
|
|
12
|
+
@title = title
|
|
13
|
+
@projects = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_project(project)
|
|
17
|
+
@projects.push(project)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def request_funding(rounds)
|
|
21
|
+
puts"There are #{ @projects.size } projects that you could fund"
|
|
22
|
+
|
|
23
|
+
@projects.each do |project|
|
|
24
|
+
puts project
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
pledges = PledgePool::PLEDGES
|
|
28
|
+
puts "\nThere are #{ pledges.size } possible pledge amounts:"
|
|
29
|
+
pledges.each do |pledge|
|
|
30
|
+
puts "A #{ pledge.name } pledge is worth $#{ pledge.amount }."
|
|
31
|
+
end
|
|
32
|
+
puts"\n"
|
|
33
|
+
|
|
34
|
+
1.upto(rounds) do |round|
|
|
35
|
+
puts"Round: #{ round }"
|
|
36
|
+
@projects.each do |project|
|
|
37
|
+
FundingRound.round(project)
|
|
38
|
+
puts "#{ project }\n\n"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def print_name_and_funding(project)
|
|
44
|
+
puts "#{ project.name } - #{ project.funding }"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def print_name(project)
|
|
48
|
+
puts "Project #{ project.name }"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def print_stats
|
|
52
|
+
puts"\n#{ fully_funded_projects.size } Fully funded projects"
|
|
53
|
+
fully_funded_projects.each do |f|
|
|
54
|
+
print_name(f)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
puts"\n#{ under_funded_projects.size } Under funded projects"
|
|
58
|
+
under_funded_projects.each do |u|
|
|
59
|
+
print_name(u)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
sorted = sorted_under_funded_projects
|
|
63
|
+
puts"\nProjects needing some donation"
|
|
64
|
+
sorted.each do |s|
|
|
65
|
+
puts under_funded_entry(s)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@projects.each do |project|
|
|
69
|
+
puts"\n#{ project.name }'s pledges:"
|
|
70
|
+
project.each_received_pledge do |pledge|
|
|
71
|
+
puts "$#{ pledge.amount } in #{ pledge.name } pledges"
|
|
72
|
+
end
|
|
73
|
+
puts "#{ project.pledges } in total pledges"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
save_under_funded_projects
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def sorted_under_funded_projects
|
|
80
|
+
under_funded_projects.sort { |a, b| b.total_funding_outstanding <=> a.total_funding_outstanding}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def fully_funded_projects
|
|
84
|
+
@projects.select { |project| project.fully_funded? }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def under_funded_projects
|
|
88
|
+
@projects.reject { |project| project.fully_funded? }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def under_funded_entry(project)
|
|
92
|
+
formatted_name = project.name.ljust(20, '.')
|
|
93
|
+
"#{ formatted_name } $#{ project.total_funding_outstanding } under"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def load_projects(from_file)
|
|
97
|
+
File.readlines(from_file).each do |line|
|
|
98
|
+
name, target_funding_amount, funding = line.split(',')
|
|
99
|
+
project = Project.new(name, Integer(target_funding_amount), Integer(funding))
|
|
100
|
+
add_project(project)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def save_under_funded_projects(to_file="results.txt")
|
|
105
|
+
File.open(to_file, "w") do |file|
|
|
106
|
+
file.puts "Projects needing some donation:"
|
|
107
|
+
sorted_under_funded_projects.each do |project|
|
|
108
|
+
file.puts(under_funded_entry(project))
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
class GrantProject < Project
|
|
5
|
+
|
|
6
|
+
def remove_funds
|
|
7
|
+
puts"No funds can be removed from a grant project"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if __FILE__ == $0
|
|
14
|
+
grant = GrantProject.new("Grant", 1_000, 300)
|
|
15
|
+
|
|
16
|
+
puts "#{grant.name} has $#{grant.total_funds} in funding towards a goal of $#{grant.target}."
|
|
17
|
+
grant.remove_funds
|
|
18
|
+
puts "#{grant.name} has $#{grant.total_funds} in funding towards a goal of $#{grant.target}."
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
class MatchingProject < Project
|
|
5
|
+
|
|
6
|
+
def initialize(name, target_funding_amount, funding = 0)
|
|
7
|
+
super(name, target_funding_amount, funding)
|
|
8
|
+
@half_amount = target_funding_amount / 2
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def half_amount?
|
|
12
|
+
@half_amount <= funding
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def add_funds
|
|
16
|
+
if half_amount?
|
|
17
|
+
@funding += (25 * 2)
|
|
18
|
+
puts "#{ name } has received at least half of its target amount"
|
|
19
|
+
else
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if __FILE__ == $0
|
|
28
|
+
matching = MatchingProject.new("Matching 123", 200, 0)
|
|
29
|
+
6.times { matching.add_funds }
|
|
30
|
+
puts matching.funding
|
|
31
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Crowdfund
|
|
2
|
+
Pledge = Struct.new(:name, :amount)
|
|
3
|
+
|
|
4
|
+
module PledgePool
|
|
5
|
+
PLEDGES = [
|
|
6
|
+
Pledge.new(:bronze, 50),
|
|
7
|
+
Pledge.new(:silver, 75),
|
|
8
|
+
Pledge.new(:gold, 100)
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
def self.random
|
|
12
|
+
PLEDGES.sample
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if __FILE__ == $0
|
|
19
|
+
puts PledgePool::PLEDGES
|
|
20
|
+
treasure = PledgePool.random
|
|
21
|
+
puts "You have received a #{pledge.name} pledge. It values $#{plege.points}"
|
|
22
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require_relative 'pledge_pool'
|
|
2
|
+
require_relative 'fundable'
|
|
3
|
+
|
|
4
|
+
module Crowdfund
|
|
5
|
+
class Project
|
|
6
|
+
include Fundable
|
|
7
|
+
|
|
8
|
+
attr_accessor :name
|
|
9
|
+
attr_reader :target, :funding
|
|
10
|
+
|
|
11
|
+
def initialize(name, target_funding_amount, funding = 0)
|
|
12
|
+
@name = name
|
|
13
|
+
@target = target_funding_amount
|
|
14
|
+
@funding = funding
|
|
15
|
+
@pledges_container = Hash.new(0)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
"#{ @name } has $#{ total_funds } in funding towards a goal of $#{ @target }."
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def received_pledge(pledge)
|
|
23
|
+
@pledges_container[pledge.name] += pledge.amount
|
|
24
|
+
puts "#{ @name } received a #{ pledge.name } pledge worth $#{ pledge.amount }."
|
|
25
|
+
puts "#{ @name }'s pledges: #{ @pledges_container }"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def pledges
|
|
29
|
+
@pledges_container.values.reduce(0, :+)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def total_funds
|
|
33
|
+
@funding + pledges
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def each_received_pledge
|
|
37
|
+
@pledges_container.each do|key, value|
|
|
38
|
+
pledge = Pledge.new(key, value)
|
|
39
|
+
yield(pledge)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if __FILE__ == $0
|
|
47
|
+
project = Project.new("LMN", 500, 3_000)
|
|
48
|
+
puts project
|
|
49
|
+
puts project.target
|
|
50
|
+
project.add_funds
|
|
51
|
+
puts project.funding
|
|
52
|
+
project.remove_funds
|
|
53
|
+
puts project.funding
|
|
54
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'crowdfund/fundrequest'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
describe FundRequest do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@fundrequest = FundRequest.new("Ruby course Crowdfunding App")
|
|
8
|
+
|
|
9
|
+
@initial_funds = 1_000
|
|
10
|
+
@project = Project.new("ABC", 5_000, @initial_funds)
|
|
11
|
+
|
|
12
|
+
@fundrequest.add_project(@project)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "adds funds to a project if an even number is rolled" do
|
|
16
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(2)
|
|
17
|
+
|
|
18
|
+
@fundrequest.request_funding(1)
|
|
19
|
+
|
|
20
|
+
expect(@project.funding).to eq(@initial_funds + 25)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "remove funds to a project if an odd number is rolled" do
|
|
24
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(1)
|
|
25
|
+
|
|
26
|
+
@fundrequest.request_funding(1)
|
|
27
|
+
|
|
28
|
+
expect(@project.funding).to eq(@initial_funds - 15)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "assigns a pledge for amount during a project's funding round" do
|
|
32
|
+
fundrequest = FundRequest.new("Ruby course Crowdfunding App")
|
|
33
|
+
project = Project.new("ABC", 5_000, @initial_funds)
|
|
34
|
+
|
|
35
|
+
fundrequest.add_project(project)
|
|
36
|
+
fundrequest.request_funding(1)
|
|
37
|
+
|
|
38
|
+
expect(project.pledges).to_not eq 0
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'crowdfund/grant_project'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
describe GrantProject do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@initial_funds = 1_000
|
|
8
|
+
@grant = GrantProject.new("Grant", 5_000, @initial_funds)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "can not have its funds removed" do
|
|
12
|
+
expect(@grant.funding).to eq 1_000
|
|
13
|
+
|
|
14
|
+
@grant.remove_funds
|
|
15
|
+
|
|
16
|
+
expect(@grant.funding).to eq @initial_funds
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'crowdfund/matching_project'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
describe MatchingProject do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@initial_funds = 0
|
|
8
|
+
@matching = MatchingProject.new("Match", 200, @initial_funds)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "does not match additional funds when the project is not halfway funded" do
|
|
12
|
+
3.times { @matching.add_funds }
|
|
13
|
+
|
|
14
|
+
expect(@matching.half_amount?).to be false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "is halfway funded when it has received half of its target funding amount" do
|
|
18
|
+
4.times { @matching.add_funds }
|
|
19
|
+
|
|
20
|
+
expect(@matching.half_amount?).to be true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "receives twice as much added funds when it is halfway funded" do
|
|
24
|
+
7.times { @matching.add_funds }
|
|
25
|
+
|
|
26
|
+
expect(@matching.funding).to eq(@initial_funds + (4 * 25)+(3 * 25 * 2))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'crowdfund/pledge_pool'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
describe Pledge do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@pledge = Pledge.new(:bronze, 50)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "has a name attribute" do
|
|
11
|
+
expect(@pledge.name).to be(:bronze)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "has an amount attribute" do
|
|
15
|
+
expect(@pledge.amount).to eq 50
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module Crowdfund
|
|
22
|
+
describe PledgePool do
|
|
23
|
+
|
|
24
|
+
it "has three pledges" do
|
|
25
|
+
expect(PledgePool::PLEDGES.size).to eq 3
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "has a bronze pledge worth $50" do
|
|
29
|
+
expect(PledgePool::PLEDGES[0]).to eq (Pledge.new(:bronze, 50))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "has a silver pledge worth 75 points" do
|
|
33
|
+
expect(PledgePool::PLEDGES[1]).to eq(Pledge.new(:silver, 75))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "has a gold pledge worth 100 points" do
|
|
37
|
+
expect(PledgePool::PLEDGES[2]).to eq(Pledge.new(:gold, 100))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "returns a random pledge" do
|
|
41
|
+
expect(PledgePool.random).to be_an_instance_of(Pledge)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'crowdfund/project'
|
|
2
|
+
|
|
3
|
+
module Crowdfund
|
|
4
|
+
describe Project do
|
|
5
|
+
before do
|
|
6
|
+
@initial_founds = 1_000
|
|
7
|
+
@project = Project.new("ABC", 5_000, @initial_founds)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "has an initial target funding amount" do
|
|
11
|
+
expect(@project.target).to eq 5_000
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "computes the total funding outstantind as the target amount minus the funding amount" do
|
|
15
|
+
expect(@project.total_funding_outstanding).to eq (5_000 - 1_000)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "increases funds by 25 when funds are added" do
|
|
19
|
+
@project.add_funds
|
|
20
|
+
|
|
21
|
+
expect(@project.funding).to eq(@initial_founds.to_i + 25)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "decreases funds by 15 when funds are removed" do
|
|
25
|
+
@project.remove_funds
|
|
26
|
+
|
|
27
|
+
expect(@project.funding).to eq(@initial_founds.to_i - 15)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "when a project is initialized with no initial funding amount" do
|
|
31
|
+
before do
|
|
32
|
+
@project = Project.new("LMN", 5_000)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "has default value of 0 for funding amount" do
|
|
36
|
+
expect(@project.funding).to eq 0
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "when total funding outstanding is less than or equals zero" do
|
|
41
|
+
before do
|
|
42
|
+
@project = Project.new("LMN", 5_000, 5_000)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "is fully funded" do
|
|
46
|
+
expect(@project).to be_fully_funded
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "when total funding outstanding is greater than zero" do
|
|
51
|
+
before do
|
|
52
|
+
@project = Project.new("LMN", 5_000, 1_000)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "is not fully funded" do
|
|
56
|
+
expect(@project).to_not be_fully_funded
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "computes pledges as the sum of all pledges" do
|
|
61
|
+
expect(@project.pledges).to eq 0
|
|
62
|
+
|
|
63
|
+
@project.received_pledge(Pledge.new(:silver, 75))
|
|
64
|
+
|
|
65
|
+
expect(@project.pledges).to eq 75
|
|
66
|
+
|
|
67
|
+
@project.received_pledge(Pledge.new(:gold, 100))
|
|
68
|
+
|
|
69
|
+
expect(@project.pledges).to eq 175
|
|
70
|
+
|
|
71
|
+
@project.received_pledge(Pledge.new(:gold, 100))
|
|
72
|
+
|
|
73
|
+
expect(@project.pledges).to eq 275
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "computes total funds as the sum of a projects funding and pledges" do
|
|
78
|
+
@project.received_pledge(Pledge.new(:gold, 100))
|
|
79
|
+
@project.received_pledge(Pledge.new(:gold, 100))
|
|
80
|
+
|
|
81
|
+
expect(@project.total_funds).to eq 1_200
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "yields each pledge received and its value" do
|
|
85
|
+
@project.received_pledge(Pledge.new(:bronze, 50))
|
|
86
|
+
@project.received_pledge(Pledge.new(:silver, 75))
|
|
87
|
+
@project.received_pledge(Pledge.new(:gold, 100))
|
|
88
|
+
|
|
89
|
+
yielded = []
|
|
90
|
+
@project.each_received_pledge do |pledge|
|
|
91
|
+
yielded << pledge
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
expect(yielded).to eq([Pledge.new(:bronze, 50),
|
|
95
|
+
Pledge.new(:silver, 75),
|
|
96
|
+
Pledge.new(:gold, 100)])
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: crowdfund_sergio_silva
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sérgio Vitarelli Silva
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-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: '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
|
+
This is an example application used in The Pragmatic Studio's
|
|
29
|
+
Ruby Programming course, as described at
|
|
30
|
+
|
|
31
|
+
http://pragmaticstudio.com
|
|
32
|
+
|
|
33
|
+
This code is Copyright 2012 The Pragmatic Studio. See the LICENSE file.
|
|
34
|
+
email: sergio.silva@dito.com.br
|
|
35
|
+
executables:
|
|
36
|
+
- crowdfund
|
|
37
|
+
extensions: []
|
|
38
|
+
extra_rdoc_files: []
|
|
39
|
+
files:
|
|
40
|
+
- LICENSE
|
|
41
|
+
- README
|
|
42
|
+
- bin/crowdfund
|
|
43
|
+
- bin/projects.csv
|
|
44
|
+
- bin/results.txt
|
|
45
|
+
- lib/crowdfund/die.rb
|
|
46
|
+
- lib/crowdfund/fundable.rb
|
|
47
|
+
- lib/crowdfund/funding_round.rb
|
|
48
|
+
- lib/crowdfund/fundrequest.rb
|
|
49
|
+
- lib/crowdfund/grant_project.rb
|
|
50
|
+
- lib/crowdfund/matching_project.rb
|
|
51
|
+
- lib/crowdfund/pledge_pool.rb
|
|
52
|
+
- lib/crowdfund/project.rb
|
|
53
|
+
- spec/crowdfund/fundrequest_spec.rb
|
|
54
|
+
- spec/crowdfund/grant_project_spec.rb
|
|
55
|
+
- spec/crowdfund/matching_project_spec.rb
|
|
56
|
+
- spec/crowdfund/pledge_pool_spec.rb
|
|
57
|
+
- spec/crowdfund/project_spec.rb
|
|
58
|
+
homepage: https://github.com/
|
|
59
|
+
licenses: []
|
|
60
|
+
metadata: {}
|
|
61
|
+
post_install_message:
|
|
62
|
+
rdoc_options: []
|
|
63
|
+
require_paths:
|
|
64
|
+
- lib
|
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '1.9'
|
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
requirements: []
|
|
76
|
+
rubyforge_project:
|
|
77
|
+
rubygems_version: 2.4.5
|
|
78
|
+
signing_key:
|
|
79
|
+
specification_version: 4
|
|
80
|
+
summary: Crowdfund application gem
|
|
81
|
+
test_files: []
|