crowdfund_alec 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 +18 -0
- data/README.md +12 -0
- data/bin/crowdfund +34 -0
- data/bin/projects.csv +3 -0
- data/lib/crowdfund/die.rb +15 -0
- data/lib/crowdfund/fund_request.rb +125 -0
- data/lib/crowdfund/fundable.rb +20 -0
- data/lib/crowdfund/funding_round.rb +19 -0
- data/lib/crowdfund/grant_project.rb +16 -0
- data/lib/crowdfund/matching_project.rb +24 -0
- data/lib/crowdfund/pledge.rb +19 -0
- data/lib/crowdfund/project.rb +68 -0
- data/spec/crowdfund/fund_request_spec.rb +28 -0
- data/spec/crowdfund/grant_project_spec.rb +14 -0
- data/spec/crowdfund/matching_project_spec.rb +30 -0
- data/spec/crowdfund/pledge_spec.rb +39 -0
- data/spec/crowdfund/project_spec.rb +105 -0
- metadata +87 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 783050b5dd00a24b8a28767bf31cbe5086eb291d48e7490ffb493a6df854f104
|
|
4
|
+
data.tar.gz: 32b0582569a592921d126cfa63664ecb98bf9c966e1c73f3c10fac79dfc746e2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f4c23651ebd47c69f1e9b4c4fff45d855769e956d6a55fe35265d867b68bc7a276305ed32080f84f1ebea84bc1bb85421e7390fcc66cfe051d6d24cc9673b92f
|
|
7
|
+
data.tar.gz: e09774c699c324d4f94e0437f913aa8e6ef77d62aa8b53b6dac67b31da6189ac261ef8a42a5c5c9f9f3241bc1f92fab444018913652a7344a1dd4582fe98685a
|
data/LICENSE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Alec
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
13
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
15
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
16
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
17
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
18
|
+
SOFTWARE.
|
data/README.md
ADDED
data/bin/crowdfund
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
begin
|
|
3
|
+
require 'crowdfund/fund_request'
|
|
4
|
+
require 'crowdfund/project'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
|
7
|
+
retry
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
project1 = Project.new("Project LMN", 5000, 3000)
|
|
11
|
+
project2 = Project.new("Project XYZ", 5000, 6000)
|
|
12
|
+
project3= Project.new("Project ABC", 5000, 2000)
|
|
13
|
+
project4= Project.new("Project TBD", 1000, 1000)
|
|
14
|
+
|
|
15
|
+
projects=FundRequest.new("Startup do Alec")
|
|
16
|
+
default_project_file = File.join(File.dirname(__FILE__), 'projects.csv')
|
|
17
|
+
projects.load_projects(ARGV.shift || default_project_file)
|
|
18
|
+
|
|
19
|
+
loop do
|
|
20
|
+
puts "How many rounds of funding? ('q' or 'e' to exit)"
|
|
21
|
+
answer = gets.chomp.downcase
|
|
22
|
+
|
|
23
|
+
case answer
|
|
24
|
+
when /^\d+$/
|
|
25
|
+
projects.request_funding(answer.to_i)
|
|
26
|
+
when 'q', 'e'
|
|
27
|
+
projects.print_results
|
|
28
|
+
projects.save_under_funded_projects
|
|
29
|
+
break
|
|
30
|
+
else
|
|
31
|
+
puts "Please enter a number or 'q'/'e'"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
data/bin/projects.csv
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
require_relative 'die'
|
|
3
|
+
require_relative 'funding_round'
|
|
4
|
+
require_relative 'pledge'
|
|
5
|
+
class FundRequest
|
|
6
|
+
attr_reader :title
|
|
7
|
+
def initialize(title)
|
|
8
|
+
@title = title
|
|
9
|
+
@projects = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load_projects(from_file)
|
|
13
|
+
File.readlines(from_file).each do |line|
|
|
14
|
+
name, fund_amount, target_fund_amount = line.split(',')
|
|
15
|
+
project = Project.new(name, Integer(fund_amount), Integer(target_fund_amount))
|
|
16
|
+
add_project(project)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def save_under_funded_projects(to_file= "needmoremoney.txt")
|
|
21
|
+
|
|
22
|
+
fully_funded_projects = @projects.select { |proj| proj.funded?}
|
|
23
|
+
under_funded_projects = @projects.reject { |proj| proj.funded?}
|
|
24
|
+
|
|
25
|
+
sorted_projects = under_funded_projects.sort { |a,b| b.funds_needed <=> a.funds_needed}
|
|
26
|
+
|
|
27
|
+
File.open(to_file, "w") do |file|
|
|
28
|
+
file.puts "#{@title} - Funding Report"
|
|
29
|
+
file.puts
|
|
30
|
+
|
|
31
|
+
file.puts "#{fully_funded_projects.size} fully funded projects"
|
|
32
|
+
fully_funded_projects.each do |proj|
|
|
33
|
+
file.puts "#{proj.name} ($#{proj.fund_amount})"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
file.puts "#{under_funded_projects.size} under funded projects"
|
|
37
|
+
#under_funded_projects.each do |proj|
|
|
38
|
+
sorted_projects.each do |project|
|
|
39
|
+
formatted_name = project.name.ljust(20, '.')
|
|
40
|
+
file.puts "#{formatted_name} $#{project.funds_needed} under"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
file.puts
|
|
44
|
+
file.puts "Project snapshots(CSV):"
|
|
45
|
+
@projects.each do |proje|
|
|
46
|
+
file.puts proje.to_csv
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
puts "Under-funded report written to #{to_file}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def add_project(a_project)
|
|
54
|
+
@projects << a_project
|
|
55
|
+
#@projects.push(a_project)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def request_funding(rounds)
|
|
59
|
+
puts "There are #{@projects.size} projects that you could fund:"
|
|
60
|
+
|
|
61
|
+
@projects.each do |p|
|
|
62
|
+
puts p
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
pledges = Pledgesmod::PLEDGES
|
|
66
|
+
puts "\nThere are #{pledges.size} possible pledge amounts:"
|
|
67
|
+
pledges.each do |p|
|
|
68
|
+
puts "A #{p.name} pledge is worth $#{p.pledge_amount}."
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
1.upto(rounds) do |round|
|
|
74
|
+
puts "\nFunding Round #{round}:"
|
|
75
|
+
@projects.each do |p|
|
|
76
|
+
FundingRound.one_round(p)
|
|
77
|
+
puts p
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def print_name_and_funding(project)
|
|
83
|
+
puts "#{project.name} ($#{project.fund_amount})"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def print_results
|
|
87
|
+
fully_funded_projects = @projects.select {|project| project.funded?}
|
|
88
|
+
under_funded_projects = @projects.reject {|project| project.funded?}
|
|
89
|
+
|
|
90
|
+
puts "\n#{fully_funded_projects.size} Projetos que atingiram a meta(Fully-funded Projects):"
|
|
91
|
+
fully_funded_projects.each do |project|
|
|
92
|
+
print_name_and_funding(project)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
puts "\n#{under_funded_projects.size} Projetos que não atingiram a meta(Under-funded Projects):"
|
|
96
|
+
under_funded_projects.each do |project|
|
|
97
|
+
print_name_and_funding(project)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
sorted_projects = under_funded_projects.sort {|a,b| b.funds_needed <=> a.funds_needed }
|
|
101
|
+
|
|
102
|
+
puts "\n#{under_funded_projects.size} projects still need your help:"
|
|
103
|
+
sorted_projects.each do |project|
|
|
104
|
+
formatted_name = project.name.ljust(20, '.')
|
|
105
|
+
puts "#{formatted_name} $#{project.funds_needed} under"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
@projects.each do |proj|
|
|
109
|
+
puts "\n#{proj.name}'s pledges:"
|
|
110
|
+
proj.each_received_pledge do |ple|
|
|
111
|
+
puts "$#{ple.pledge_amount} in #{ple.name} pledges"
|
|
112
|
+
end
|
|
113
|
+
puts "$#{proj.pledges} in total pledges"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
if __FILE__ == $0
|
|
118
|
+
project1 = Project.new("Project LMN", 5000, 3000)
|
|
119
|
+
project2 = Project.new("Project XYZ", 5000, 6000)
|
|
120
|
+
projectsun=FundRequest.new("Startup do Alec")
|
|
121
|
+
puts projectsun.title
|
|
122
|
+
projectsun.add_project(project1)
|
|
123
|
+
projectsun.add_project(project2)
|
|
124
|
+
projectsun.request_funding
|
|
125
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Fundable
|
|
2
|
+
#remove #add #total #fully
|
|
3
|
+
def remove_fund
|
|
4
|
+
@fund_amount -=15
|
|
5
|
+
"#{@name} lost $15 in funds!"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def add_fund
|
|
9
|
+
@fund_amount +=25
|
|
10
|
+
"#{@name} got $25 in funds!"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def funds_needed
|
|
14
|
+
@target_fund_amount - @fund_amount
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def funded?
|
|
18
|
+
funds_needed <= 0
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
require_relative 'die'
|
|
3
|
+
require_relative 'pledge'
|
|
4
|
+
|
|
5
|
+
module FundingRound
|
|
6
|
+
def self.one_round(project)
|
|
7
|
+
die = Die.new
|
|
8
|
+
number_rolled = die.roll
|
|
9
|
+
if number_rolled.odd?
|
|
10
|
+
project.remove_fund
|
|
11
|
+
else
|
|
12
|
+
project.add_fund
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
pledge = Pledgesmod.random
|
|
16
|
+
project.received_pledge(pledge)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
|
|
3
|
+
class GrantProject < Project
|
|
4
|
+
def remove_fund
|
|
5
|
+
@fund_amount -= 0
|
|
6
|
+
puts "#{@name} has not lost or gained any new funds."
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
if __FILE__ == $0
|
|
11
|
+
grant = GrantProject.new("Project 123", 500, 100)
|
|
12
|
+
|
|
13
|
+
puts "#{grant.name} has $#{grant.total_funds} in funding towards a goal of $#{grant.target_fund_amount}."
|
|
14
|
+
grant.remove_fund
|
|
15
|
+
puts "#{grant.name} has $#{grant.total_funds} in funding towards a goal of $#{grant.target_fund_amount}."
|
|
16
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'project'
|
|
2
|
+
|
|
3
|
+
class MatchingProject < Project
|
|
4
|
+
def initialize(name, fund_amount, target_fund_amount=0.00 )
|
|
5
|
+
super(name, fund_amount, target_fund_amount)
|
|
6
|
+
@halfway_funded = target_fund_amount/2
|
|
7
|
+
end
|
|
8
|
+
def halfway_funded?
|
|
9
|
+
@halfway_funded <= fund_amount
|
|
10
|
+
end
|
|
11
|
+
def add_fund
|
|
12
|
+
if halfway_funded?
|
|
13
|
+
@fund_amount += (25*2)
|
|
14
|
+
puts "#{@name} has received at least half its funding!" if halfway_funded?
|
|
15
|
+
else
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
if __FILE__ == $0
|
|
21
|
+
matchingproject= MatchingProject.new("Matching 123", 0, 100)
|
|
22
|
+
3.times {matchingproject.add_fund}
|
|
23
|
+
puts matchingproject.fund_amount
|
|
24
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Pledge = Struct.new(:name, :pledge_amount)
|
|
2
|
+
|
|
3
|
+
module Pledgesmod
|
|
4
|
+
PLEDGES = [
|
|
5
|
+
Pledge.new(:bronze, 50),
|
|
6
|
+
Pledge.new(:silver, 75),
|
|
7
|
+
Pledge.new(:gold, 100)
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
def self.random
|
|
11
|
+
PLEDGES.sample
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __FILE__ == $0
|
|
18
|
+
puts Pledgesmod::PLEDGES
|
|
19
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require_relative 'pledge'
|
|
2
|
+
require_relative 'fundable'
|
|
3
|
+
class Project
|
|
4
|
+
include Fundable
|
|
5
|
+
attr_reader :fund_amount, :target_fund_amount
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
def initialize(name, fund_amount, target_fund_amount=0.00)
|
|
8
|
+
@name=name
|
|
9
|
+
@fund_amount=fund_amount
|
|
10
|
+
@target_fund_amount=target_fund_amount
|
|
11
|
+
@received_pledge = Hash.new(0)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.from_csv(line)
|
|
15
|
+
name, fund_amount, target_fund_amount = line.split(',')
|
|
16
|
+
Project.new(name, Integer(fund_amount), Integer(target_fund_amount))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_csv
|
|
20
|
+
"#{@name}, #{@fund_amount}, #{@target_fund_amount}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
if funded?
|
|
25
|
+
sobra = @fund_amount - @target_fund_amount
|
|
26
|
+
"#{@name} has $#{@fund_amount} in funds (goal: $#{@target_fund_amount}). Goal achieved! Surplus of $#{sobra}." else
|
|
27
|
+
falta = funds_needed
|
|
28
|
+
"#{@name} has $#{@fund_amount} in funds (goal: $#{@target_fund_amount}). Still needs $#{funds_needed}." end
|
|
29
|
+
end
|
|
30
|
+
def received_pledge(pledge)
|
|
31
|
+
@received_pledge[pledge.name] += pledge.pledge_amount
|
|
32
|
+
puts "#{@name} received a #{pledge.name} pledge worth $#{pledge.pledge_amount}."
|
|
33
|
+
puts "#{@name}'s pledges: #{@received_pledge}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def pledges
|
|
37
|
+
@received_pledge.values.reduce(0,:+)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def total_funds
|
|
41
|
+
@fund_amount + pledges
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def status
|
|
48
|
+
if funded?
|
|
49
|
+
"#{@name} has reached the goal of $#{@target_fund_amount} with $#{@fund_amount}."
|
|
50
|
+
else
|
|
51
|
+
"#{@name} has not yet reached the goal of $#{@target_fund_amount}. (Still needs $#{funds_needed}.)"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def each_received_pledge
|
|
56
|
+
@received_pledge.each do |name, amount|
|
|
57
|
+
yield Pledge.new(name, amount)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
if __FILE__ == $0
|
|
62
|
+
project3= Project.new("Project ABC", 5000, 2000)
|
|
63
|
+
project4= Project.new("Project TBD", 1000, 1000)
|
|
64
|
+
puts project3.status
|
|
65
|
+
puts "*****"
|
|
66
|
+
puts project4.remove_fund
|
|
67
|
+
puts project4
|
|
68
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'crowdfund/fund_request'
|
|
2
|
+
describe FundRequest do
|
|
3
|
+
before do
|
|
4
|
+
@fundrequest = FundRequest.new("Fundação de doações")
|
|
5
|
+
|
|
6
|
+
@fund_amount = 1000
|
|
7
|
+
@target_fund_amount = 5000
|
|
8
|
+
@project = Project.new("Project ABC", @fund_amount, @target_fund_amount)
|
|
9
|
+
|
|
10
|
+
@fundrequest.add_project(@project)
|
|
11
|
+
$stdout = StringIO.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "Adds funds to a project if a even number is rolled" do
|
|
15
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(4)
|
|
16
|
+
|
|
17
|
+
@fundrequest.request_funding(2)
|
|
18
|
+
|
|
19
|
+
expect(@project.fund_amount).to eq(@fund_amount + (25*2))
|
|
20
|
+
end
|
|
21
|
+
it "removes funds to a project if an odd number is rolled" do
|
|
22
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(3)
|
|
23
|
+
|
|
24
|
+
@fundrequest.request_funding(2)
|
|
25
|
+
|
|
26
|
+
expect(@project.fund_amount).to eq(@fund_amount - (15*2))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'crowdfund/grant_project'
|
|
2
|
+
|
|
3
|
+
describe GrantProject do
|
|
4
|
+
before do
|
|
5
|
+
@initial_funds = 1000
|
|
6
|
+
@project = GrantProject.new("Grant 123", @initial_funds, 5000)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "does not ever have funds removed" do
|
|
10
|
+
@project.remove_fund
|
|
11
|
+
expect(@project.fund_amount).to eq(@initial_funds)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'crowdfund/matching_project'
|
|
2
|
+
|
|
3
|
+
describe MatchingProject do
|
|
4
|
+
before do
|
|
5
|
+
@initial_funds = 0
|
|
6
|
+
@project = MatchingProject.new("Match 123", @initial_funds, 200)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "does not match additional funds when the project is not halfway funded" do
|
|
10
|
+
3.times { @project.add_fund}
|
|
11
|
+
#@project.halfway_funded?.should be_falsey
|
|
12
|
+
expect(@project.halfway_funded?).to be_falsey
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "is halfway funded when it has received half of its target funding amount" do
|
|
16
|
+
4.times { @project.add_fund }
|
|
17
|
+
|
|
18
|
+
#@project.halfway_funded?.should be_truthy
|
|
19
|
+
expect(@project.halfway_funded?).to be_truthy
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "receives twice as much added funds when it is halfway funded" do
|
|
23
|
+
7.times { @project.add_fund }
|
|
24
|
+
|
|
25
|
+
#@project.fund_amount.should == @initial_funds + (4 * 25) + (3 * 25 * 2)
|
|
26
|
+
expect(@project.fund_amount). to eq(((@initial_funds) + (4*25)+(3*25*2)))
|
|
27
|
+
expect(@project.fund_amount).to eq((@initial_funds+(4 * 25) + (3 * 25 * 2)))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'crowdfund/pledge'
|
|
2
|
+
describe Pledge do
|
|
3
|
+
before do
|
|
4
|
+
@pledge = Pledge.new(:gold, 100)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
it "has a name attribute" do
|
|
8
|
+
expect(@pledge.name).to eq(:gold)
|
|
9
|
+
end
|
|
10
|
+
it "has a points attribute" do
|
|
11
|
+
expect(@pledge.pledge_amount).to eq(100)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe Pledgesmod do
|
|
17
|
+
|
|
18
|
+
it "has a three pledges" do
|
|
19
|
+
expect(Pledgesmod::PLEDGES.size).to eq(3)
|
|
20
|
+
end
|
|
21
|
+
it "has a bronze give $50" do
|
|
22
|
+
expect(Pledgesmod::PLEDGES[0]).to eq(Pledge.new(:bronze, 50))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "has a silver give $75" do
|
|
26
|
+
expect(Pledgesmod::PLEDGES[1]).to eq(Pledge.new(:silver, 75))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "has a gold give $100" do
|
|
30
|
+
expect(Pledgesmod::PLEDGES[2]).to eq(Pledge.new(:gold, 100))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "returns a random pledge" do
|
|
34
|
+
pledge = Pledgesmod.random
|
|
35
|
+
|
|
36
|
+
expect(Pledgesmod::PLEDGES).to include(pledge)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'crowdfund/project'
|
|
2
|
+
|
|
3
|
+
describe Project do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
@fund_amount = 1000
|
|
7
|
+
@target_fund_amount = 5000
|
|
8
|
+
@project = Project.new("Project ABC", @fund_amount, @target_fund_amount)
|
|
9
|
+
$stdout = StringIO.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "has an initial target funding amount" do
|
|
13
|
+
expect(@project.target_fund_amount).to eq(@target_fund_amount)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "computes the total funds outstandings as the target funding amount minus the funding amount" do
|
|
17
|
+
expect(@project.funds_needed).to eq(@target_fund_amount - @fund_amount)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "increases funds by 25 when funds are added" do
|
|
21
|
+
@project.add_fund
|
|
22
|
+
|
|
23
|
+
expect(@project.fund_amount).to eq(@fund_amount + 25)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "decreases funds by 15 when funds are removed" do
|
|
27
|
+
@project.remove_fund
|
|
28
|
+
|
|
29
|
+
expect(@project.fund_amount).to eq(@fund_amount - 15)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when total funding outstanding is less than or equal to 0" do
|
|
33
|
+
before do
|
|
34
|
+
@project = Project.new("Project ABC", 5000, 5000)
|
|
35
|
+
end
|
|
36
|
+
it "Atingiu a meta?" do
|
|
37
|
+
expect(@project.funded?).to eq(true)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "when total funding outstanding is greater than 0" do
|
|
42
|
+
before do
|
|
43
|
+
@project= Project.new("Project ABC", 1000, 5000)
|
|
44
|
+
end
|
|
45
|
+
it "is under-funded" do
|
|
46
|
+
expect(@project.funded?).to eq(false)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
=begin
|
|
58
|
+
it "Todo projeto possui um nome" do
|
|
59
|
+
expect(@project.project).to eq("Project ABC")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "Todo projeto vem por padrão com sua meta zerada caso não seja informada" do
|
|
63
|
+
@project1 = Project.new("Projeto sem meta", 5000)
|
|
64
|
+
expect(@project1.target_fund_amount).to eq(0.00)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "Todo projeto possui um valor inicial" do
|
|
68
|
+
expect(@project.fund_amount).to eq(5000)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "Todo projeto possui uma meta" do
|
|
72
|
+
expect(@project.target_fund_amount).to eq(2000)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "Soma 25 no valor incial(add_fund)" do
|
|
76
|
+
@project.add_fund
|
|
77
|
+
expect(@project.fund_amount).to eq(5025)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "Subtrai 15 do valor inicial(remove_fund)" do
|
|
81
|
+
@project.remove_fund
|
|
82
|
+
expect(@project.fund_amount).to eq(4985)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "Possui um método String para representar(to_s)" do
|
|
86
|
+
expect(@project.to_s).to eq("Project ABC tem $5000 em doações e sua meta é $2000, portanto, atingiu sua meta e ainda passou $3000.")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "Quanto falta para bater a meta?" do
|
|
90
|
+
expect(@project.how_much_is_left?).to eq(-3000)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "Atingiu a meta?" do
|
|
94
|
+
@project.atingiu_meta?
|
|
95
|
+
expect(@project.atingiu_meta?).to eq(true)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "Mostrar o status do andamento do projeto" do
|
|
99
|
+
@project.status
|
|
100
|
+
expect(@project.status).to eq("Project ABC atingiu a meta de 2000 com $5000.")
|
|
101
|
+
end
|
|
102
|
+
=end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: crowdfund_alec
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- LucioAlec
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rspec
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '3'
|
|
26
|
+
description: |-
|
|
27
|
+
# Flicks
|
|
28
|
+
|
|
29
|
+
Command-line app/gem to fundfraising program.
|
|
30
|
+
|
|
31
|
+
## Run from source
|
|
32
|
+
ruby bin/crowdfund
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
- Load players from CSV
|
|
36
|
+
- Points system (blam/w00t)
|
|
37
|
+
- Treasure trove
|
|
38
|
+
- Clumsy and beserker player
|
|
39
|
+
email: lucioalec@gmail.com
|
|
40
|
+
executables:
|
|
41
|
+
- crowdfund
|
|
42
|
+
extensions: []
|
|
43
|
+
extra_rdoc_files: []
|
|
44
|
+
files:
|
|
45
|
+
- LICENSE
|
|
46
|
+
- README.md
|
|
47
|
+
- bin/crowdfund
|
|
48
|
+
- bin/projects.csv
|
|
49
|
+
- lib/crowdfund/die.rb
|
|
50
|
+
- lib/crowdfund/fund_request.rb
|
|
51
|
+
- lib/crowdfund/fundable.rb
|
|
52
|
+
- lib/crowdfund/funding_round.rb
|
|
53
|
+
- lib/crowdfund/grant_project.rb
|
|
54
|
+
- lib/crowdfund/matching_project.rb
|
|
55
|
+
- lib/crowdfund/pledge.rb
|
|
56
|
+
- lib/crowdfund/project.rb
|
|
57
|
+
- spec/crowdfund/fund_request_spec.rb
|
|
58
|
+
- spec/crowdfund/grant_project_spec.rb
|
|
59
|
+
- spec/crowdfund/matching_project_spec.rb
|
|
60
|
+
- spec/crowdfund/pledge_spec.rb
|
|
61
|
+
- spec/crowdfund/project_spec.rb
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata: {}
|
|
65
|
+
rdoc_options: []
|
|
66
|
+
require_paths:
|
|
67
|
+
- lib
|
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '2.5'
|
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
requirements: []
|
|
79
|
+
rubygems_version: 3.6.9
|
|
80
|
+
specification_version: 4
|
|
81
|
+
summary: Manage a fundraising program with a roll die
|
|
82
|
+
test_files:
|
|
83
|
+
- spec/crowdfund/fund_request_spec.rb
|
|
84
|
+
- spec/crowdfund/grant_project_spec.rb
|
|
85
|
+
- spec/crowdfund/matching_project_spec.rb
|
|
86
|
+
- spec/crowdfund/pledge_spec.rb
|
|
87
|
+
- spec/crowdfund/project_spec.rb
|