je_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.
- 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
|