Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
285 commits
Select commit Hold shift + click to select a range
0ca6862
song test #3-just write it down
skmetz May 14, 2020
8fbc519
add case 6/7 to verse
skmetz May 14, 2020
5cdb6b1
revert case 6/7
skmetz May 14, 2020
8bbdda7
interpolate number in 2 case
skmetz May 14, 2020
6472691
fling entire container method in
skmetz May 14, 2020
bcf2570
revert prior change
skmetz May 14, 2020
8bf693d
add empty container method
skmetz May 14, 2020
2ffce1e
return 'bottles' in container
skmetz May 14, 2020
1ce89b7
send #container in default
skmetz May 14, 2020
8bbad05
add defaulted arg to container
skmetz May 14, 2020
30f83f4
add entire conditional to container
skmetz May 14, 2020
103e78d
pass arg when sending #container
skmetz May 14, 2020
a27d249
use #container in 2 case
skmetz May 14, 2020
bb70758
remove obsolete default arg
skmetz May 14, 2020
c557716
delete obsolete 2 case
skmetz May 14, 2020
acc5aea
interpolate number at start of 1 case
skmetz May 14, 2020
70a1d30
send #container in phrase 1 case 1
skmetz May 14, 2020
821013c
make phrase 1/2 of case 1/else identical
skmetz May 14, 2020
bef2d99
add pronoun
skmetz May 14, 2020
ab7f687
pronoun returns 'one'
skmetz May 14, 2020
dc3c163
send pronoun in else
skmetz May 14, 2020
008ec30
add defaulted arg to pronoun
skmetz May 14, 2020
ebb9f06
use pronoun arg in if statement
skmetz May 14, 2020
8be9e2e
pass arg to pronoun in else
skmetz May 14, 2020
0092a4f
use pronoun arg in 1 case
skmetz May 14, 2020
d7e7407
remove obsolete arg from pronoun
skmetz May 14, 2020
12ecb9b
add quantity
skmetz May 14, 2020
e7914ac
quantity returns 'no more'
skmetz May 14, 2020
9ce9cb7
1 case sends quantity
skmetz May 14, 2020
66721ac
add arg and wrong default to quantity
skmetz May 14, 2020
d5610c9
use wrong default in quantity conditional
skmetz May 14, 2020
ad81c88
revert to green
skmetz May 14, 2020
b8e4da6
set quantity arg default to correct value
skmetz May 14, 2020
3af4d67
use correct default in quantity conditional
skmetz May 14, 2020
a7d9f5d
send quantity(arg) in case 1 phrase 4
skmetz May 14, 2020
e81781a
send quantity(arg) in else phrase 4
skmetz May 14, 2020
50742cd
remove obsolete default
skmetz May 14, 2020
3eaf43f
send container in case 1 phrase 4
skmetz May 14, 2020
3200230
delete case 1
skmetz May 14, 2020
97a6894
send quantity in case 0 phrase 1
skmetz May 14, 2020
40abbcf
send quantity in else phrase 1, FAILS
skmetz May 14, 2020
557aec5
hack to_s in else case to sidestep error
skmetz May 14, 2020
6ff0514
add unneeded to_s to 1 case to make them the same
skmetz May 14, 2020
78194c5
add to_s to #quantity, return a capitalizable
skmetz May 14, 2020
b1a6915
remove obsolete to_s's
skmetz May 14, 2020
e996aef
send container in case 0 phrase 1
skmetz May 14, 2020
7c03081
send quantity in else phrase 2
skmetz May 14, 2020
20785df
make case 0 phrase 2 like else phrase 2
skmetz May 14, 2020
1144261
add complete #action
skmetz May 14, 2020
e7b14e3
use #action
skmetz May 14, 2020
9434089
send #quantity(99)
skmetz May 14, 2020
1fb7d1f
send container in case 0 phrase 4
skmetz May 14, 2020
61ad1c5
add #successor(number)
skmetz May 14, 2020
f9fa810
send #successor in else phrase 4
skmetz May 14, 2020
c3132b8
add conditional to #successor
skmetz May 14, 2020
9cbd3b8
replace 99 with successor(number)
skmetz May 14, 2020
37ce41f
use successor everywhere
skmetz May 14, 2020
f98d9d8
try common template
skmetz May 14, 2020
2fa7d05
delete obsolete code
skmetz May 14, 2020
89a4874
wrap long lines in verse
skmetz May 15, 2020
a3214ee
add empty BottleNumber class
skmetz May 15, 2020
f6e5a12
copy obsessive methods to BottleNumber
skmetz May 15, 2020
a504be3
add attr_reader and initializer
skmetz May 15, 2020
0052ae4
parse/exec BottleNumber#quantity
skmetz May 15, 2020
08ce5ca
use BottleNumber#quantity result
skmetz May 15, 2020
1456e3d
delete obsolete code
skmetz May 15, 2020
3e4f06a
parse/exec BottleNumber#container
skmetz May 15, 2020
f8e6cad
use BottleNumber#container result
skmetz May 15, 2020
fc3a435
delete obsolete code
skmetz May 15, 2020
52e384c
parse/exec BottleNumber#action
skmetz May 15, 2020
b43f221
use BottleNumber#action result
skmetz May 15, 2020
8ee2229
delete obsolete code
skmetz May 15, 2020
bf42aa3
parse/exec BottleNumber#pronoun
skmetz May 15, 2020
d764d71
use BottleNumber#pronoun result
skmetz May 15, 2020
e20667d
delete obsolete code
skmetz May 15, 2020
70f4cba
parse/exec BottleNumber#successor
skmetz May 15, 2020
6c2d3c4
use BottleNumber#successor result
skmetz May 15, 2020
cb95f42
delete obsolete code
skmetz May 15, 2020
d3be56c
rename BottleNumber#quantity argument
skmetz May 15, 2020
3b4c7c7
remove param from sender
skmetz May 15, 2020
8f2e7c1
remove arg from receiver
skmetz May 15, 2020
185c027
rename BottleNumber#container argument
skmetz May 15, 2020
72f88ac
remove param from sender
skmetz May 15, 2020
62b1d14
remove arg from receiver
skmetz May 15, 2020
9517843
rename BottleNumber#action argument
skmetz May 15, 2020
79caa4f
remove param from sender
skmetz May 15, 2020
538dcd3
remove arg from receiver
skmetz May 15, 2020
61f863d
rename BottleNumber#pronoun argument
skmetz May 15, 2020
d9f0321
remove param from unused sender
skmetz May 15, 2020
fb2bc41
remove arg from receiver FAIL
skmetz May 15, 2020
eaad2d1
revert prior change
skmetz May 15, 2020
630c8d9
delete unused Bottles#pronoun
skmetz May 15, 2020
461ed1f
remove param from sender
skmetz May 15, 2020
7d01c25
remove arg from receiver
skmetz May 15, 2020
32879ab
rename BottleNumber#successor argument
skmetz May 15, 2020
c2f1969
remove param from sender
skmetz May 15, 2020
a95fde7
remove arg from receiver
skmetz May 15, 2020
3437f44
cache (memoize) a BottleNumber
skmetz May 15, 2020
4725db6
send #action to bottle_number
skmetz May 15, 2020
516815e
use bottle_number is phrase 1
skmetz May 15, 2020
6fd6864
use bottle_number is phrase 2
skmetz May 15, 2020
0c87e3f
cache (memoize) the next BottleNumber
skmetz May 15, 2020
ed83d22
use next_bottle_number is phrase 4
skmetz May 15, 2020
24cd637
delete obsolete code
skmetz May 15, 2020
f52bff9
add BottleNumber#to_s
skmetz May 16, 2020
8f8a6fa
use to_s in phrase 1
skmetz May 16, 2020
5d8ec82
use to_s in phrase 2
skmetz May 16, 2020
e17527e
use to_s in phrase 4
skmetz May 16, 2020
7f4a20e
unite phrase 1 on single line
skmetz May 16, 2020
221ca49
consolidate phrase 1 strings
skmetz May 16, 2020
5697969
unite phrase 4 on single line
skmetz May 16, 2020
0788ebb
consolidate phrase 4 strings
skmetz May 16, 2020
5af6dc5
create BottleNumber0 class
skmetz May 16, 2020
1bbb637
copy #quantity to BottleNumber0
skmetz May 16, 2020
2560fde
reduce #quantity to specialization
skmetz May 16, 2020
5a4b552
add #bottle_number_for
skmetz May 16, 2020
f74faa7
use #bottle_number_for once
skmetz May 16, 2020
1bf280f
use #bottle_number_for twice
skmetz May 16, 2020
92b0eb0
manufacture a bottle number
skmetz May 16, 2020
b5ce952
parse an alternate factory impl
skmetz May 16, 2020
ccf8a14
use the alternate implementation
skmetz May 16, 2020
cf4c4e0
reduce super #quantity to generalization
skmetz May 16, 2020
e0dd252
copy #action to BottleNumber0
skmetz May 16, 2020
092f8ff
return specialization
skmetz May 16, 2020
8b5f746
delete obsolete code
skmetz May 16, 2020
aa8f07c
return super's generalization
skmetz May 16, 2020
b6fdef9
delete obsolete code
skmetz May 16, 2020
b4d21fa
copy #successor to BottleNumber0
skmetz May 16, 2020
e6da42d
return specialization
skmetz May 16, 2020
1add2f0
delete obsolete code
skmetz May 16, 2020
6b84117
return super's generalization
skmetz May 16, 2020
dc8f6f0
delete obsolete code
skmetz May 16, 2020
9d33dc3
create BottleNumber1 class
skmetz May 16, 2020
2016970
copy #container to BottleNumber1
skmetz May 16, 2020
4911a71
return specialization
skmetz May 16, 2020
4d3c261
delete obsolete code
skmetz May 16, 2020
186c5d3
return super's generalization FAIL
skmetz May 16, 2020
fe798c1
revert previous change
skmetz May 16, 2020
59c082e
parse updated factory
skmetz May 16, 2020
ff6ec76
use updated factory
skmetz May 16, 2020
9f65bc2
return super's #container generalization
skmetz May 16, 2020
45ecfe5
delete obsolete code
skmetz May 16, 2020
2513f12
copy #pronoun to BottleNumber1
skmetz May 16, 2020
c1fb91a
return specialization
skmetz May 16, 2020
3769e8e
return super's generalization
skmetz May 16, 2020
6ff93e1
delete obsolete code
skmetz May 16, 2020
796af14
wish for a smarter successor
skmetz May 16, 2020
6df27d9
copy #bottle_number_for to BottleNumber.for
skmetz May 16, 2020
d7a5902
use .for factory once
skmetz May 16, 2020
65b3382
use .for factory twice
skmetz May 16, 2020
6e56684
delete obsolete code
skmetz May 16, 2020
eb3fdfe
add type check guard clause to BottleNumber.for
skmetz May 16, 2020
887c43b
return a bottle number from BottleNumber0#successor
skmetz May 16, 2020
6047d03
return a bottle number from BottleNumber#successor
skmetz May 16, 2020
da026bf
see if the successor wish now works
skmetz May 16, 2020
6f1be7e
delete obsolete code
skmetz May 16, 2020
bc631cd
inline next_bottle_number temp
skmetz May 16, 2020
c096ebf
delete obsolete code
skmetz May 16, 2020
1231ac9
delete obsolete code
skmetz May 16, 2020
7c6e55a
add six-pack to song test
skmetz May 16, 2020
e14ef35
create BottleNumber6 class
skmetz May 16, 2020
9fd416b
add BottleNumber6#container
skmetz May 16, 2020
5cb00be
add BottleNumber6 to factory
skmetz May 16, 2020
2e7f20c
add BottleNumber6#quantity
skmetz May 16, 2020
aef5a8f
parse metaprogrammed factory
skmetz May 16, 2020
010e4a9
use metaprogrammed factory
skmetz May 16, 2020
30b6bcc
parse Hash factory
skmetz May 16, 2020
5191ef7
use Hash factory
skmetz May 16, 2020
110c9a1
add handles? method to BottleNumber6
skmetz May 16, 2020
acd1b26
add handles? method to BottleNumber1
skmetz May 16, 2020
d5f88ac
add handles? method to BottleNumber0
skmetz May 16, 2020
3e87528
add handles? method to BottleNumber
skmetz May 16, 2020
256209a
parse dispersed choosing logic factory
skmetz May 16, 2020
b4547c1
use dispersed choosing logic factory
skmetz May 16, 2020
c6b43f5
add BottleNumber.registry
skmetz May 16, 2020
17eb5ec
add BottleNumber.register
skmetz May 16, 2020
c289215
register BottleNumber6
skmetz May 16, 2020
b84bb4c
register BottleNumber1
skmetz May 16, 2020
125c2ce
register BottleNumber0
skmetz May 16, 2020
041d86e
register BottleNumber
skmetz May 16, 2020
5844efa
parse self registering factory
skmetz May 16, 2020
d314080
use self registering factory
skmetz May 16, 2020
dcd89fa
override inherited hook
skmetz May 16, 2020
6a30763
delete obsolete code
skmetz May 16, 2020
ef3b303
initialize registry with BottleNumber
skmetz May 16, 2020
e2705c2
delete obsolete code
skmetz May 16, 2020
80a299e
revert to simplest factory
skmetz May 16, 2020
e197539
create BottleVerse class
skmetz May 16, 2020
05271ab
add attr_reader and initialize number
skmetz May 16, 2020
5809b5f
copy #verse from Bottles to BottleVerse
skmetz May 16, 2020
0b4fc0b
parse/exec new #verse from old #verse
skmetz May 16, 2020
a6fa17f
use result of new #verse
skmetz May 16, 2020
5500fad
revert to old #verse
skmetz May 16, 2020
a093565
wish to send #lyrics
skmetz May 16, 2020
51cd64f
change BottleVerse#verse(number) to BottleVerse#lyrics
skmetz May 16, 2020
8d6c5e2
parse/exec sending #lyrics
skmetz May 16, 2020
d0131e9
use result of sending #lyrics
skmetz May 16, 2020
806010f
wish to depend of verse template role
skmetz May 16, 2020
1c8cb79
inject verse_template role
skmetz May 16, 2020
84b7470
use result from verse template role
skmetz May 16, 2020
0645b1d
wish for lyrics without Demeter violation
skmetz May 16, 2020
b1d8df7
add BottleVerse.lyrics to make wish possible
skmetz May 16, 2020
6a7c11b
retrieve lyrics without Demeter violation
skmetz May 16, 2020
13ac11a
wish to consolidate object creation
skmetz May 16, 2020
37b5bd7
lyrics works with numbers or bottle numbers
skmetz May 16, 2020
e50aef8
parse/exec wish
skmetz May 16, 2020
18be38b
use result of consolidated object creation wish
skmetz May 16, 2020
16cf1cc
remove number to bottle number conversion from #lyrics
skmetz May 16, 2020
4ecee97
add bottle_number attr_reader
skmetz May 16, 2020
7f9ffca
initialize bottle_number
skmetz May 16, 2020
311964a
delete obsolete code
skmetz May 16, 2020
df2001d
add alternate initializer
skmetz May 16, 2020
dcfee21
use alternate initializer
skmetz May 16, 2020
2e6bdd2
delete obsolete code
skmetz May 16, 2020
01e9e91
add BottleVerseTest
skmetz May 18, 2020
a4c95cb
copy 1st test from BottlesTest to BottleVerseTest
skmetz May 18, 2020
3d951cc
use BottleVerse in 1st test
skmetz May 18, 2020
c26aa74
delete obsolete test
skmetz May 18, 2020
f6500a3
copy all other verse tests into BottleVerseTest
skmetz May 18, 2020
0daf8e5
make 1 undo regexp change from Bottles to BottleVerse
skmetz May 18, 2020
f486a9d
delete obsolete test
skmetz May 18, 2020
11a76e5
rename lower bound test
skmetz May 18, 2020
1b0fb4b
rename upper bound test
skmetz May 18, 2020
8cee690
add verse 7 test
skmetz May 18, 2020
5a607bd
add verse 6 test
skmetz May 18, 2020
2a1343f
duplicate Bottles as CountdownSong
skmetz May 18, 2020
97c47d4
change BottlesTest to CountdownSongTest
skmetz May 18, 2020
7be7c1a
change Bottles to CountdownSong (1 undo change)
skmetz May 18, 2020
6dcd624
delete obsolete Bottles class
skmetz May 18, 2020
fed47c5
add VerseFake
skmetz May 18, 2020
9a0a0ba
create alternate test_a_couple_verses method
skmetz May 18, 2020
c23fd06
use VerseFake in alternate couple_verses test
skmetz May 18, 2020
2fadf4d
delete obsolete test
skmetz May 18, 2020
e34d2ac
delete redundant test_a_few_verses
skmetz May 18, 2020
3c27f0a
add verse test
skmetz May 18, 2020
bd0ebf3
rename verses test
skmetz May 18, 2020
d034b91
create max and min attr_readers
skmetz May 18, 2020
650cbdd
initialize max and min
skmetz May 18, 2020
db9d103
use max and min in #song
skmetz May 18, 2020
413d9dc
add alternate #test_the_whole_song
skmetz May 18, 2020
1ce274b
delete obsolete test
skmetz May 18, 2020
0ec49e9
rename song test
skmetz May 19, 2020
ff4f96c
move VerseFake to top of file
skmetz May 19, 2020
b8b6864
add verse role test
skmetz May 19, 2020
6650516
set @role_player in BotttleVerseTest#setup
skmetz May 19, 2020
cc55fae
include VerseRoleTest in BottleVerseTest
skmetz May 19, 2020
4eb1c60
create VerseFakeTest
skmetz May 28, 2020
21affb8
remove verse_template default
skmetz Jun 17, 2020
4d130d6
set max default to 999999
skmetz Jun 17, 2020
7aaed88
Initial refactoring
JonahHouseKin Jan 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source 'https://rubygems.org'
gem 'minitest', '~> 5.4'
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
GEM
remote: https://rubygems.org/
specs:
minitest (5.14.0)

PLATFORMS
ruby

DEPENDENCIES
minitest (~> 5.4)

BUNDLED WITH
2.1.4
90 changes: 90 additions & 0 deletions lib/bottles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
class CountdownSong
attr_reader :verse_template, :max, :min

def initialize(verse_template:, max: 999999, min: 0)
@verse_template = verse_template
@max, @min = max, min
end

def song
verses(max, min)
end

def verses(upper, lower)
upper.downto(lower).collect {|i| verse(i)}.join("\n")
end

def verse(number)
verse_template.lyrics(number)
end
end


class BottleVerse
def self.lyrics(number)
new(BottleNumber.new(number)).lyrics
end

attr_reader :bottle_number

def initialize(bottle_number)
@bottle_number = bottle_number
end

def lyrics
"#{bottle_number} of beer on the wall, ".capitalize +
"#{bottle_number} of beer.\n" +
"#{bottle_number.action}, " +
"#{bottle_number.successor} of beer on the wall.\n"
end
end


class BottleNumber
attr_reader :number
def initialize(number)
@number = number
end

def to_s
"#{quantity} #{container}"
end

def quantity
BOTTLE_NUMBER_DEFAULTS[number]&.[](:quantity) || number.to_s
end

def container
BOTTLE_NUMBER_DEFAULTS[number]&.[](:container) || "bottles"
end

def action
BOTTLE_NUMBER_DEFAULTS[number]&.[](:action) || "Take #{pronoun} down and pass it around"
end

def pronoun
BOTTLE_NUMBER_DEFAULTS[number]&.[](:pronoun) || "one"
end

def successor
BOTTLE_NUMBER_DEFAULTS[number]&.[](:successor) ? BottleNumber.new(BOTTLE_NUMBER_DEFAULTS[number]&.[](:successor)) : BottleNumber.new(number - 1)
end
end

BOTTLE_NUMBER_DEFAULTS = {
0 => {
quantity: "no more",
action: "Go to the store and buy some more",
successor: 99
},
1 => {
container: "bottle",
pronoun: "it"
},
6 => {
quantity: "1",
container: "six-pack"
}
}

pp BOTTLE_NUMBER_DEFAULTS[9]&.[](:quantity)
139 changes: 139 additions & 0 deletions test/bottles_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
gem 'minitest', '~> 5.4'
require 'minitest/autorun'
require 'minitest/pride'
require_relative '../lib/bottles'

module VerseRoleTest
def test_plays_verse_role
assert_respond_to @role_player, :lyrics
end
end

class VerseFake
def self.lyrics(number)
"This is verse #{number}.\n"
end
end

class VerseFakeTest < Minitest::Test
include VerseRoleTest

def setup
@role_player = VerseFake
end
end


class BottleVerseTest < Minitest::Test
include VerseRoleTest

def setup
@role_player = BottleVerse
end

def test_verse_general_rule_upper_bound
expected =
"99 bottles of beer on the wall, " +
"99 bottles of beer.\n" +
"Take one down and pass it around, " +
"98 bottles of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(99)
end

def test_verse_general_rule_lower_bound
expected =
"3 bottles of beer on the wall, " +
"3 bottles of beer.\n" +
"Take one down and pass it around, " +
"2 bottles of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(3)
end

def test_verse_7
expected =
"7 bottles of beer on the wall, " +
"7 bottles of beer.\n" +
"Take one down and pass it around, " +
"1 six-pack of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(7)
end

def test_verse_6
expected =
"1 six-pack of beer on the wall, " +
"1 six-pack of beer.\n" +
"Take one down and pass it around, " +
"5 bottles of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(6)
end

def test_verse_2
expected =
"2 bottles of beer on the wall, " +
"2 bottles of beer.\n" +
"Take one down and pass it around, " +
"1 bottle of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(2)
end

def test_verse_1
expected =
"1 bottle of beer on the wall, " +
"1 bottle of beer.\n" +
"Take it down and pass it around, " +
"no more bottles of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(1)
end

def test_verse_0
expected =
"No more bottles of beer on the wall, " +
"no more bottles of beer.\n" +
"Go to the store and buy some more, " +
"99 bottles of beer on the wall.\n"
assert_equal expected, BottleVerse.lyrics(0)
end
end


class CountdownSongTest < Minitest::Test
def test_verse
expected = "This is verse 500.\n"
assert_equal(
expected,
CountdownSong.new(verse_template: VerseFake)
.verse(500))
end

def test_verses
expected =
"This is verse 99.\n" +
"\n" +
"This is verse 98.\n" +
"\n" +
"This is verse 97.\n"
assert_equal(
expected,
CountdownSong.new(verse_template: VerseFake)
.verses(99, 97))
end

def test_song
expected =
"This is verse 47.\n" +
"\n" +
"This is verse 46.\n" +
"\n" +
"This is verse 45.\n" +
"\n" +
"This is verse 44.\n" +
"\n" +
"This is verse 43.\n"
assert_equal(
expected,
CountdownSong.new(verse_template: VerseFake,
max: 47,
min: 43)
.song)
end
end