je_crowdfund 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +19 -0
- data/README.md +3 -0
- data/bin/crowdfund +33 -0
- data/bin/project_list.csv +3 -0
- data/lib/crowdfund/die.rb +13 -0
- data/lib/crowdfund/fundable.rb +19 -0
- data/lib/crowdfund/funding_round.rb +17 -0
- data/lib/crowdfund/fundrequest.rb +65 -0
- data/lib/crowdfund/government_match_project.rb +15 -0
- data/lib/crowdfund/grant_project.rb +24 -0
- data/lib/crowdfund/pledge_pool.rb +17 -0
- data/lib/crowdfund/pledgeable.rb +19 -0
- data/lib/crowdfund/project.rb +45 -0
- data/spec/crowdfund/fundrequest_spec.rb +29 -0
- data/spec/crowdfund/government_match_project_spec.rb +29 -0
- data/spec/crowdfund/grant_project_spec.rb +23 -0
- data/spec/crowdfund/pledge_pool_spec.rb +45 -0
- data/spec/crowdfund/project_spec.rb +107 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: eecf1a23692aa22c3ec570eea372ddecf925e591ccc681419f5d8edb8fc12711
|
4
|
+
data.tar.gz: 9019a82ce5ea00ed98d256b3fa29619f51132ec41596401e4a67059eec12e9f7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ad2b8173657f52c6bc140d5fd44a6b0970501d1d00f1feea5bc719d2e29080fc15b4d9bccf020efe0426d4548b6bc3bdc4b006712041da73e36691058b43d42
|
7
|
+
data.tar.gz: 4b1a273469f6bb1972a11ac46183a1fb866cf0ea1a19532f9d5b7dcbe5a1349de57336c4e273d177ccdf908dee97559350b5ab6b685717990515ec52956b6969
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2021 Jonathan Eccles
|
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
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
data/bin/crowdfund
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/crowdfund/fundrequest'
|
4
|
+
|
5
|
+
# project1 = Project.new("wooden whistle", 600, 500, 1)
|
6
|
+
# project2 = Project.new("paper notebook", 150)
|
7
|
+
# project3 = Project.new("brush", 100, 0)
|
8
|
+
|
9
|
+
crowd_list = CrowdFund::FundRequest.new("crowd funding")
|
10
|
+
# crowd_list.add_project(project1)
|
11
|
+
# crowd_list.add_project(project2)
|
12
|
+
# crowd_list.add_project(project3)
|
13
|
+
|
14
|
+
crowd_list.load_projects(File.join(File.dirname(__FILE__), 'project_list.csv'))
|
15
|
+
|
16
|
+
rounds = ARGV.shift || "1"
|
17
|
+
crowd_list.request_funding(rounds.to_i)
|
18
|
+
|
19
|
+
loop do
|
20
|
+
puts("\nRun another funding roung? (y/n): ")
|
21
|
+
answer = gets.chomp.downcase
|
22
|
+
case answer
|
23
|
+
when 'y', 'yes'
|
24
|
+
crowd_list.request_funding(1)
|
25
|
+
when 'n', 'no', 'x', 'q', 'quit', 'exit'
|
26
|
+
crowd_list.print_stats
|
27
|
+
break
|
28
|
+
else
|
29
|
+
puts "Enter 'y' or 'n' only"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
crowd_list.save_unfunded_projects("#{crowd_list.name.downcase.gsub(' ', '_')}_unfunded_projects.txt")
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CrowdFund
|
2
|
+
module Fundable
|
3
|
+
def funded?
|
4
|
+
funding_gap <= 0
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_funds(amount = 25)
|
8
|
+
self.funding += amount
|
9
|
+
self.backers += 1
|
10
|
+
puts "Project #{name} got an addtional £#{amount} in funding!"
|
11
|
+
end
|
12
|
+
|
13
|
+
def remove_funds(amount = 15)
|
14
|
+
self.funding -= amount
|
15
|
+
self.backers -= 1
|
16
|
+
puts "Project #{name} lost £#{amount} in funding!"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'die'
|
2
|
+
require_relative 'pledge_pool'
|
3
|
+
|
4
|
+
module CrowdFund
|
5
|
+
module FundingRound
|
6
|
+
def self.one_round(project)
|
7
|
+
die = Die.new
|
8
|
+
@number_rolled = die.roll
|
9
|
+
if @number_rolled.even?
|
10
|
+
project.add_funds
|
11
|
+
else
|
12
|
+
project.remove_funds
|
13
|
+
end
|
14
|
+
project.record_pledge(PledgePool.random)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require_relative 'project'
|
3
|
+
require_relative 'funding_round'
|
4
|
+
|
5
|
+
module CrowdFund
|
6
|
+
class FundRequest
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name.capitalize
|
11
|
+
@projects = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_projects(filename)
|
15
|
+
CSV.foreach(filename) do |line|
|
16
|
+
add_project(Project.from_csv(line))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def save_unfunded_projects(to_file = "unfunded_projects.txt")
|
21
|
+
File.open(to_file, "w") do |file|
|
22
|
+
file.puts "#{@name} Unfunded Projects:"
|
23
|
+
under_funded = @projects.filter { |p| p.funded? == false }
|
24
|
+
under_funded.sort.each { |uf| file.puts uf.name_and_funding }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_project(project)
|
29
|
+
@projects << project
|
30
|
+
end
|
31
|
+
|
32
|
+
def request_funding(rounds)
|
33
|
+
puts "There are #{@projects.size} projects in the #{@name} project list:"
|
34
|
+
puts @projects
|
35
|
+
|
36
|
+
1.upto(rounds) do |round|
|
37
|
+
puts "\nRound: #{round}"
|
38
|
+
@projects.each do |project|
|
39
|
+
FundingRound.one_round(project)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
print_stats
|
44
|
+
end
|
45
|
+
|
46
|
+
def print_stats
|
47
|
+
puts "\nFunding Results"
|
48
|
+
|
49
|
+
fully_funded, under_funded = @projects.partition { |p| p.funded? }
|
50
|
+
puts "\n#{fully_funded.size} projects funded"
|
51
|
+
fully_funded.each {|ff| puts ff.name_and_funding}
|
52
|
+
|
53
|
+
puts "\n#{under_funded.size} projects under funded"
|
54
|
+
under_funded.sort.each {|uf| puts uf.name_and_funding}
|
55
|
+
|
56
|
+
@projects.sort.each do |project|
|
57
|
+
puts "\nProject #{project.name}'s pledges:"
|
58
|
+
project.each_donated_pledge do |pledge|
|
59
|
+
puts "£#{pledge.amount} in #{pledge.name} pledges"
|
60
|
+
end
|
61
|
+
puts "£#{project.pledges} in total pledges"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'project'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
class GovernmentMatchProject < Project
|
5
|
+
def initialize(name, funding_goal, funding = 0, backers = 0)
|
6
|
+
super(name, funding_goal, funding, backers)
|
7
|
+
@name = "[GOV MATCH] #{name.capitalize}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_funds(amount = 25)
|
11
|
+
super(amount) if funding_gap <= @funding_goal / 2
|
12
|
+
super(amount)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'project'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
class GrantProject < Project
|
5
|
+
def initialize(name, funding_goal, funding = 0, backers = 0)
|
6
|
+
super(name, funding_goal, funding, backers)
|
7
|
+
@name = "[GRANT] #{name.capitalize}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_funds(amount = 0)
|
11
|
+
puts "Project #{@name} is a Grant Project and cannot have funds removed!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if __FILE__ == $0
|
16
|
+
grant = GrantProject.new("battery", 150)
|
17
|
+
puts grant.name_and_funding
|
18
|
+
grant.add_funds(100)
|
19
|
+
2.times { grant.add_funds }
|
20
|
+
puts grant.name_and_funding
|
21
|
+
8.times { grant.remove_funds }
|
22
|
+
puts grant.name_and_funding
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CrowdFund
|
2
|
+
Pledge = Struct.new(:name, :amount)
|
3
|
+
|
4
|
+
module PledgePool
|
5
|
+
|
6
|
+
PLEDGES = [
|
7
|
+
Pledge.new(:base, 25),
|
8
|
+
Pledge.new(:bronze, 50),
|
9
|
+
Pledge.new(:silver, 75),
|
10
|
+
Pledge.new(:gold, 100)
|
11
|
+
]
|
12
|
+
|
13
|
+
def self.random
|
14
|
+
PLEDGES.sample
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CrowdFund
|
2
|
+
module Pledgeable
|
3
|
+
def record_pledge(pledge)
|
4
|
+
self.pledges_received[pledge.name] += pledge.amount
|
5
|
+
puts "Project #{name} received a #{pledge.name} pledge worth £#{pledge.amount}."
|
6
|
+
puts "Project #{name}\s pledges #{pledges_received}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def pledges
|
10
|
+
pledges_received.values.reduce(0, :+)
|
11
|
+
end
|
12
|
+
|
13
|
+
def each_donated_pledge
|
14
|
+
pledges_received.each do |name, points|
|
15
|
+
yield(Pledge.new(name, points))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'fundable'
|
2
|
+
require_relative 'pledgeable'
|
3
|
+
|
4
|
+
module CrowdFund
|
5
|
+
class Project
|
6
|
+
include Fundable, Pledgeable
|
7
|
+
|
8
|
+
attr_reader :funding_goal
|
9
|
+
attr_accessor :name, :funding, :backers, :pledges_received
|
10
|
+
|
11
|
+
def initialize(name, funding_goal, funding = 0, backers = 0)
|
12
|
+
@name = name.capitalize
|
13
|
+
@funding_goal = funding_goal
|
14
|
+
@funding = funding
|
15
|
+
@backers = backers
|
16
|
+
@pledges_received = Hash.new(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_csv(csv_line)
|
20
|
+
Project.new(csv_line[0], Integer(csv_line[1]), Integer(csv_line[2]), Integer(csv_line[3]))
|
21
|
+
end
|
22
|
+
|
23
|
+
def funding_gap
|
24
|
+
funding_goal - funding - pledges
|
25
|
+
end
|
26
|
+
|
27
|
+
def name_and_funding
|
28
|
+
"#{@name.ljust(20, '.')} £#{@funding + pledges} of £#{@funding_goal}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def <=>(project)
|
32
|
+
project.funding_gap <=> self.funding_gap
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"Project #{@name} has £#{@funding + pledges} in funding and pledges from #{@backers} backer(s) towards a goal of £#{@funding_goal} leaving a gap of £#{funding_gap} as of #{Time.now.strftime("%F %T")}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
if __FILE__ == $0
|
42
|
+
project1 = Project.new("testbed", 1000, 500, 10)
|
43
|
+
puts project1
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'crowdfund/fundrequest'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
describe FundRequest do
|
5
|
+
before do
|
6
|
+
$stdout = StringIO.new
|
7
|
+
@crowd_list = FundRequest.new("crowd funding")
|
8
|
+
@project1 = Project.new("wooden whistle", 600, 500, 1)
|
9
|
+
@crowd_list.add_project(@project1)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "adds funds if an even number is rolled" do
|
13
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(2)
|
14
|
+
|
15
|
+
expect{ @crowd_list.request_funding(2) }.to change(@project1, :funding).by(25 * 2)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "removes funds if an odd number is rolled" do
|
19
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(5)
|
20
|
+
|
21
|
+
expect{ @crowd_list.request_funding(2) }.to change(@project1, :funding).by(-15 * 2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "assigns a pledge for funding during a project funding round" do
|
25
|
+
@crowd_list.request_funding(1)
|
26
|
+
expect(@project1.pledges).to_not be_zero
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'crowdfund/government_match_project'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
describe GovernmentMatchProject do
|
5
|
+
before do
|
6
|
+
$stdout = StringIO.new
|
7
|
+
@initial_funding = 150
|
8
|
+
@initial_backers = 1
|
9
|
+
@funding_goal = 1000
|
10
|
+
@name = "hover car"
|
11
|
+
@match = GovernmentMatchProject.new(@name, @funding_goal, @initial_funding, @initial_backers)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a capitalized name" do
|
15
|
+
expect(@match.name).to eq("[GOV MATCH] #{@name.capitalize}")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not match funds while under half funded" do
|
19
|
+
amount = 150
|
20
|
+
expect{ @match.add_funds(amount) }.to change(@match, :funding).by(150)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "matches additional funds when projects are at least half funded" do
|
24
|
+
amount = 100
|
25
|
+
@match.add_funds(350)
|
26
|
+
expect{ @match.add_funds(amount) }.to change(@match, :funding).by(200)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'crowdfund/grant_project'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
describe GrantProject do
|
5
|
+
before do
|
6
|
+
$stdout = StringIO.new
|
7
|
+
@initial_funding = 150
|
8
|
+
@initial_backers = 1
|
9
|
+
@funding_goal = 10000
|
10
|
+
@name = "hover car"
|
11
|
+
@grant = GrantProject.new(@name, @funding_goal, @initial_funding, @initial_backers)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a capitalized name" do
|
15
|
+
expect(@grant.name).to eq("[GRANT] #{@name.capitalize}")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not decrease funds when funds are removed" do
|
19
|
+
amount = 15
|
20
|
+
expect{ @grant.remove_funds(amount) }.to change(@grant, :funding).by(0)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'crowdfund/pledge_pool'
|
2
|
+
|
3
|
+
module CrowdFund
|
4
|
+
describe Pledge do
|
5
|
+
before do
|
6
|
+
@pledge = Pledge.new(:silver, 75)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has a name attribute" do
|
10
|
+
expect(@pledge.name).to eq(:silver)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has a points attribute" do
|
14
|
+
expect(@pledge.amount).to eq(75)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe PledgePool do
|
19
|
+
it "has four pledge levels" do
|
20
|
+
expect(PledgePool::PLEDGES.size).to eq(4)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a base level worth 25" do
|
24
|
+
expect(PledgePool::PLEDGES[0]).to eq(Pledge.new(:base, 25))
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a bronze level worth £50" do
|
28
|
+
expect(PledgePool::PLEDGES[1]).to eq(Pledge.new(:bronze, 50))
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has a silver level worth £50" do
|
32
|
+
expect(PledgePool::PLEDGES[2]).to eq(Pledge.new(:silver, 75))
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has a gold level worth £100" do
|
36
|
+
expect(PledgePool::PLEDGES[3]).to eq(Pledge.new(:gold, 100))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a random pledge" do
|
40
|
+
pledge = PledgePool.random
|
41
|
+
|
42
|
+
expect(PledgePool::PLEDGES).to include(pledge)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'crowdfund/project'
|
2
|
+
require 'crowdfund/pledge_pool'
|
3
|
+
|
4
|
+
module CrowdFund
|
5
|
+
describe Project do
|
6
|
+
before do
|
7
|
+
$stdout = StringIO.new
|
8
|
+
@initial_funding = 150
|
9
|
+
@initial_backers = 1
|
10
|
+
@funding_goal = 10000
|
11
|
+
@name = "hover car"
|
12
|
+
@project = Project.new(@name, @funding_goal, @initial_funding, @initial_backers)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has a capitalized name" do
|
16
|
+
expect(@project.name).to eq(@name.capitalize)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has an initial target funding goal" do
|
20
|
+
expect(@project.funding_goal).not_to eq(0)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "computes the total funding outstanding as the target funding amount minus the funding amount" do
|
24
|
+
expect(@project.funding_gap).to eq(@project.funding_goal - @initial_funding)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "increases funds by 25 when funds are added" do
|
28
|
+
amount = 25
|
29
|
+
expect{ @project.add_funds(amount) }.to change(@project, :funding).by(amount)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "increases backers by 1 when funds are added" do
|
33
|
+
amount = 25
|
34
|
+
expect{ @project.add_funds(amount) }.to change(@project, :backers).by(1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "decreases funds by 15 when funds are removed" do
|
38
|
+
amount = 15
|
39
|
+
expect{ @project.remove_funds(amount) }.to change(@project, :funding).by(-amount)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "decreases backers by 1 when funds are removed" do
|
43
|
+
amount = 15
|
44
|
+
expect{ @project.remove_funds(amount) }.to change(@project, :backers).by(-1)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "is not fully funded when funding < funding_goal" do
|
48
|
+
expect(@project.funded?).to eq(false)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "yields each pledge level and its total value" do
|
52
|
+
@project.record_pledge(Pledge.new(:gold, 100))
|
53
|
+
@project.record_pledge(Pledge.new(:gold, 100))
|
54
|
+
@project.record_pledge(Pledge.new(:silver, 75))
|
55
|
+
@project.record_pledge(Pledge.new(:bronze, 50))
|
56
|
+
@project.record_pledge(Pledge.new(:bronze, 50))
|
57
|
+
@project.record_pledge(Pledge.new(:bronze, 50))
|
58
|
+
@project.record_pledge(Pledge.new(:base, 25))
|
59
|
+
@project.record_pledge(Pledge.new(:base, 25))
|
60
|
+
|
61
|
+
pledged = []
|
62
|
+
@project.each_donated_pledge do |pledge|
|
63
|
+
pledged << pledge
|
64
|
+
end
|
65
|
+
|
66
|
+
expect(pledged).to eq([
|
67
|
+
Pledge.new(:gold, 200),
|
68
|
+
Pledge.new(:silver, 75),
|
69
|
+
Pledge.new(:bronze, 150),
|
70
|
+
Pledge.new(:base, 50)
|
71
|
+
])
|
72
|
+
end
|
73
|
+
|
74
|
+
it "can be created from a CSV string" do
|
75
|
+
aggregate_failures "from_csv record" do
|
76
|
+
project = Project.from_csv(["jon", "200", "0", "0"])
|
77
|
+
|
78
|
+
expect(project.name).to eq("Jon")
|
79
|
+
expect(project.funding_goal).to eq(200)
|
80
|
+
expect(project.funding).to eq(0)
|
81
|
+
expect(project.backers).to eq(0)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
context "created with a default funding amount" do
|
87
|
+
before do
|
88
|
+
@project = Project.new(@name, @funding_goal)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "has a default value of 0 for funding amount" do
|
92
|
+
expect(@project.funding).to eq(0)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "fully funded" do
|
97
|
+
before do
|
98
|
+
@initial_funding = @funding_goal
|
99
|
+
@project = Project.new(@name, @funding_goal, @initial_funding, @intial_backers)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "is fully funded when funding gap <= 0" do
|
103
|
+
expect(@project.funded?).to eq(true)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: je_crowdfund
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Eccles
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-05 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: '3.10'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.10.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.10'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.10.0
|
33
|
+
description: "The [Pragmatic Studios](https://pragmaticstudio.com) Crowd Fund bonus
|
34
|
+
game created in their Learn Ruby course. \n\nProjects can be added, funded, have
|
35
|
+
funds removed and received pledges. There may also be some special types of project
|
36
|
+
lurking..."
|
37
|
+
email: getjon@me.com
|
38
|
+
executables:
|
39
|
+
- crowdfund
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- LICENSE.txt
|
44
|
+
- README.md
|
45
|
+
- bin/crowdfund
|
46
|
+
- bin/project_list.csv
|
47
|
+
- lib/crowdfund/die.rb
|
48
|
+
- lib/crowdfund/fundable.rb
|
49
|
+
- lib/crowdfund/funding_round.rb
|
50
|
+
- lib/crowdfund/fundrequest.rb
|
51
|
+
- lib/crowdfund/government_match_project.rb
|
52
|
+
- lib/crowdfund/grant_project.rb
|
53
|
+
- lib/crowdfund/pledge_pool.rb
|
54
|
+
- lib/crowdfund/pledgeable.rb
|
55
|
+
- lib/crowdfund/project.rb
|
56
|
+
- spec/crowdfund/fundrequest_spec.rb
|
57
|
+
- spec/crowdfund/government_match_project_spec.rb
|
58
|
+
- spec/crowdfund/grant_project_spec.rb
|
59
|
+
- spec/crowdfund/pledge_pool_spec.rb
|
60
|
+
- spec/crowdfund/project_spec.rb
|
61
|
+
homepage: https://pragmaticstudio.com/courses/ruby
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.9'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubygems_version: 3.1.4
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Pragmatic Studio Ruby course Crowd Funding bonus game
|
84
|
+
test_files:
|
85
|
+
- spec/crowdfund/project_spec.rb
|
86
|
+
- spec/crowdfund/pledge_pool_spec.rb
|
87
|
+
- spec/crowdfund/fundrequest_spec.rb
|
88
|
+
- spec/crowdfund/government_match_project_spec.rb
|
89
|
+
- spec/crowdfund/grant_project_spec.rb
|