Skip to content

Commit 05d72ff

Browse files
authored
Add templates for exercises batch 3 (#1773)
* Add templates for exercises batch 3 * Fix exercise naming in generator (#1770) (#1777) * Enhance underscore method to filter invalid characters and update test file naming convention * Add test case which test underscore for special characters * Use character classes in regex. Also expose description for nested test cases. * Underscore must not create multiple underscores around special characters * Change to single quotes, change conditional statement
1 parent b42bdfd commit 05d72ff

File tree

15 files changed

+440
-131
lines changed

15 files changed

+440
-131
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require 'minitest/autorun'
2+
require_relative 'circular_buffer'
3+
4+
class CircularBufferTest < Minitest::Test
5+
<% json["cases"].each do |cases| %>
6+
def test_<%= underscore(cases["description"]) %>
7+
<%= skip? %>
8+
buffer = CircularBuffer.new(<%= cases["input"]["capacity"] %>)
9+
<%- cases["input"]["operations"].each do |operation| -%>
10+
<%- if operation["operation"] == "read"-%>
11+
<%- if operation["should_succeed"] -%>
12+
assert_equal '<%= operation["expected"] %>', buffer.read
13+
<%- else -%>
14+
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
15+
<%- end -%>
16+
<%- elsif operation["operation"] == "write" -%>
17+
<%- if operation["should_succeed"] -%>
18+
buffer.write('<%= operation["item"] %>')
19+
<%- else -%>
20+
assert_raises(CircularBuffer::BufferFullException) { buffer.write('<%= operation["item"] %>') }
21+
<%- end -%>
22+
<%- elsif operation["operation"] == "overwrite" -%>
23+
buffer.write!('<%= operation["item"] %>')
24+
<% elsif operation["operation"] == "clear" -%>
25+
buffer.clear
26+
<%- end -%>
27+
<%- end -%>
28+
end
29+
<% end %>
30+
end

exercises/practice/circular-buffer/circular_buffer_test.rb

Lines changed: 81 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,107 +2,131 @@
22
require_relative 'circular_buffer'
33

44
class CircularBufferTest < Minitest::Test
5-
def test_read_empty_buffer_throws_buffer_empty_exception
5+
def test_reading_empty_buffer_should_fail
6+
# skip
67
buffer = CircularBuffer.new(1)
78
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
89
end
910

10-
def test_write_and_read_back_one_item
11+
def test_can_read_an_item_just_written
1112
skip
1213
buffer = CircularBuffer.new(1)
13-
buffer.write '1'
14+
buffer.write('1')
1415
assert_equal '1', buffer.read
15-
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
1616
end
1717

18-
def test_write_and_read_back_multiple_items
18+
def test_each_item_may_only_be_read_once
1919
skip
20-
buffer = CircularBuffer.new(2)
21-
buffer.write '1'
22-
buffer.write '2'
20+
buffer = CircularBuffer.new(1)
21+
buffer.write('1')
2322
assert_equal '1', buffer.read
24-
assert_equal '2', buffer.read
2523
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
2624
end
2725

28-
def test_clearing_buffer
26+
def test_items_are_read_in_the_order_they_are_written
2927
skip
30-
buffer = CircularBuffer.new(3)
31-
('1'..'3').each { |i| buffer.write i }
32-
buffer.clear
33-
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
34-
buffer.write '1'
35-
buffer.write '2'
28+
buffer = CircularBuffer.new(2)
29+
buffer.write('1')
30+
buffer.write('2')
3631
assert_equal '1', buffer.read
37-
buffer.write '3'
3832
assert_equal '2', buffer.read
3933
end
4034

41-
def test_alternate_write_and_read
35+
def test_full_buffer_cant_be_written_to
4236
skip
43-
buffer = CircularBuffer.new(2)
44-
buffer.write '1'
37+
buffer = CircularBuffer.new(1)
38+
buffer.write('1')
39+
assert_raises(CircularBuffer::BufferFullException) { buffer.write('2') }
40+
end
41+
42+
def test_a_read_frees_up_capacity_for_another_write
43+
skip
44+
buffer = CircularBuffer.new(1)
45+
buffer.write('1')
4546
assert_equal '1', buffer.read
46-
buffer.write '2'
47+
buffer.write('2')
4748
assert_equal '2', buffer.read
4849
end
4950

50-
def test_reads_back_oldest_item
51+
def test_read_position_is_maintained_even_across_multiple_writes
5152
skip
5253
buffer = CircularBuffer.new(3)
53-
buffer.write '1'
54-
buffer.write '2'
55-
buffer.read
56-
buffer.write '3'
54+
buffer.write('1')
55+
buffer.write('2')
56+
assert_equal '1', buffer.read
57+
buffer.write('3')
5758
assert_equal '2', buffer.read
5859
assert_equal '3', buffer.read
5960
end
6061

61-
def test_writing_to_a_full_buffer_throws_an_exception
62+
def test_items_cleared_out_of_buffer_cant_be_read
6263
skip
63-
buffer = CircularBuffer.new(2)
64-
buffer.write '1'
65-
buffer.write '2'
66-
assert_raises(CircularBuffer::BufferFullException) { buffer.write 'A' }
64+
buffer = CircularBuffer.new(1)
65+
buffer.write('1')
66+
buffer.clear
67+
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
6768
end
6869

69-
def test_overwriting_oldest_item_in_a_full_buffer
70+
def test_clear_frees_up_capacity_for_another_write
7071
skip
71-
buffer = CircularBuffer.new(2)
72-
buffer.write '1'
73-
buffer.write '2'
74-
buffer.write! 'A'
72+
buffer = CircularBuffer.new(1)
73+
buffer.write('1')
74+
buffer.clear
75+
buffer.write('2')
7576
assert_equal '2', buffer.read
76-
assert_equal 'A', buffer.read
77-
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
7877
end
7978

80-
def test_forced_writes_to_non_full_buffer_should_behave_like_writes
79+
def test_clear_does_nothing_on_empty_buffer
80+
skip
81+
buffer = CircularBuffer.new(1)
82+
buffer.clear
83+
buffer.write('1')
84+
assert_equal '1', buffer.read
85+
end
86+
87+
def test_overwrite_acts_like_write_on_non_full_buffer
8188
skip
8289
buffer = CircularBuffer.new(2)
83-
buffer.write '1'
84-
buffer.write! '2'
90+
buffer.write('1')
91+
buffer.write!('2')
8592
assert_equal '1', buffer.read
8693
assert_equal '2', buffer.read
87-
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
8894
end
8995

90-
def test_alternate_read_and_write_into_buffer_overflow
96+
def test_overwrite_replaces_the_oldest_item_on_full_buffer
97+
skip
98+
buffer = CircularBuffer.new(2)
99+
buffer.write('1')
100+
buffer.write('2')
101+
buffer.write!('3')
102+
assert_equal '2', buffer.read
103+
assert_equal '3', buffer.read
104+
end
105+
106+
def test_overwrite_replaces_the_oldest_item_remaining_in_buffer_following_a_read
91107
skip
92-
buffer = CircularBuffer.new(5)
93-
('1'..'3').each { |i| buffer.write i }
94-
buffer.read
95-
buffer.read
96-
buffer.write '4'
97-
buffer.read
98-
('5'..'8').each { |i| buffer.write i }
99-
buffer.write! 'A'
100-
buffer.write! 'B'
101-
('6'..'8').each do |i|
102-
assert_equal i, buffer.read
103-
end
104-
assert_equal 'A', buffer.read
105-
assert_equal 'B', buffer.read
108+
buffer = CircularBuffer.new(3)
109+
buffer.write('1')
110+
buffer.write('2')
111+
buffer.write('3')
112+
assert_equal '1', buffer.read
113+
buffer.write('4')
114+
buffer.write!('5')
115+
assert_equal '3', buffer.read
116+
assert_equal '4', buffer.read
117+
assert_equal '5', buffer.read
118+
end
119+
120+
def test_initial_clear_does_not_affect_wrapping_around
121+
skip
122+
buffer = CircularBuffer.new(2)
123+
buffer.clear
124+
buffer.write('1')
125+
buffer.write('2')
126+
buffer.write!('3')
127+
buffer.write!('4')
128+
assert_equal '3', buffer.read
129+
assert_equal '4', buffer.read
106130
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
107131
end
108132
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
require 'minitest/autorun'
2+
require_relative 'crypto_square'
3+
4+
class CryptoSquareTest < Minitest::Test
5+
<% json["cases"].each do |cases| %>
6+
def test_<%= underscore(cases["description"]) %>
7+
<%= skip? %>
8+
plaintext = '<%= cases["input"]["plaintext"] %>'
9+
assert_equal '<%= cases["expected"] %>', Crypto.new(plaintext).ciphertext
10+
end
11+
<% end %>
12+
end

exercises/practice/crypto-square/.meta/tests.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@ description = "8 character plaintext results in 3 chunks, the last one with a tr
3232

3333
[fbcb0c6d-4c39-4a31-83f6-c473baa6af80]
3434
description = "54 character plaintext results in 7 chunks, the last two with trailing spaces"
35+
include = false
36+
37+
[33fd914e-fa44-445b-8f38-ff8fbc9fe6e6]
38+
description = "54 character plaintext results in 8 chunks, the last two with trailing spaces"
39+
reimplements = "fbcb0c6d-4c39-4a31-83f6-c473baa6af80"

exercises/practice/crypto-square/crypto_square_test.rb

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,49 @@
44
class CryptoSquareTest < Minitest::Test
55
def test_empty_plaintext_results_in_an_empty_ciphertext
66
# skip
7-
plaintext = ""
8-
assert_equal "", Crypto.new(plaintext).ciphertext
7+
plaintext = ''
8+
assert_equal '', Crypto.new(plaintext).ciphertext
99
end
1010

1111
def test_normalization_results_in_empty_plaintext
1212
skip
13-
plaintext = "... --- ..."
14-
assert_equal "", Crypto.new(plaintext).ciphertext
13+
plaintext = '... --- ...'
14+
assert_equal '', Crypto.new(plaintext).ciphertext
1515
end
1616

1717
def test_lowercase
1818
skip
19-
plaintext = "A"
20-
assert_equal "a", Crypto.new(plaintext).ciphertext
19+
plaintext = 'A'
20+
assert_equal 'a', Crypto.new(plaintext).ciphertext
2121
end
2222

2323
def test_remove_spaces
2424
skip
25-
plaintext = " b "
26-
assert_equal "b", Crypto.new(plaintext).ciphertext
25+
plaintext = ' b '
26+
assert_equal 'b', Crypto.new(plaintext).ciphertext
2727
end
2828

2929
def test_remove_punctuation
3030
skip
31-
plaintext = "@1,%!"
32-
assert_equal "1", Crypto.new(plaintext).ciphertext
31+
plaintext = '@1,%!'
32+
assert_equal '1', Crypto.new(plaintext).ciphertext
3333
end
3434

3535
def test_9_character_plaintext_results_in_3_chunks_of_3_characters
3636
skip
37-
plaintext = "This is fun!"
38-
assert_equal "tsf hiu isn", Crypto.new(plaintext).ciphertext
37+
plaintext = 'This is fun!'
38+
assert_equal 'tsf hiu isn', Crypto.new(plaintext).ciphertext
3939
end
4040

4141
def test_8_character_plaintext_results_in_3_chunks_the_last_one_with_a_trailing_space
4242
skip
43-
plaintext = "Chill out."
44-
assert_equal "clu hlt io ", Crypto.new(plaintext).ciphertext
43+
plaintext = 'Chill out.'
44+
assert_equal 'clu hlt io ', Crypto.new(plaintext).ciphertext
4545
end
4646

47-
def test_54_character_plaintext_results_in_7_chunks_the_last_two_with_trailing_spaces
47+
def test_54_character_plaintext_results_in_8_chunks_the_last_two_with_trailing_spaces
4848
skip
49-
plaintext = "If man was meant to stay on the ground, god would have given us roots."
50-
assert_equal "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau ", Crypto.new(plaintext).ciphertext
49+
plaintext = 'If man was meant to stay on the ground, god would have given us roots.'
50+
assert_equal 'imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau ', Crypto.new(plaintext).ciphertext
5151
end
5252
end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require 'minitest/autorun'
2+
require_relative 'custom_set'
3+
4+
class CustomSetTest < Minitest::Test
5+
<% json["cases"].each do |cases| %>
6+
<% cases["cases"].each do |sub_case| %>
7+
def test_<%= underscore(sub_case["description"]) %>
8+
<%= skip? %>
9+
<%- if sub_case["input"].key?("set") -%>
10+
set = CustomSet.new <%= sub_case["input"]["set"] %>
11+
<%- if sub_case["property"] == "empty" -%>
12+
<%= sub_case["expected"] ? "assert" : "refute" %>_empty set
13+
<%- elsif sub_case["property"] == "contains" -%>
14+
element = <%= sub_case["input"]["element"] %>
15+
<%= sub_case["expected"] ? "assert" : "refute" %> set.member? element
16+
<%- elsif sub_case["property"] == "add" -%>
17+
expected = CustomSet.new <%= sub_case["expected"] %>
18+
assert_equal expected, set.add(<%= sub_case["input"]["element"] %>)
19+
<%- end -%>
20+
<%- else -%>
21+
set1 = CustomSet.new <%= sub_case["input"]["set1"] %>
22+
set2 = CustomSet.new <%= sub_case["input"]["set2"] %>
23+
<%- if sub_case["property"] == "subset" -%>
24+
<%= sub_case["expected"] ? "assert" : "refute" %> set1.subset? set2
25+
<%- elsif sub_case["property"] == "disjoint" -%>
26+
<%= sub_case["expected"] ? "assert" : "refute" %> set1.disjoint? set2
27+
<%- elsif sub_case["property"] == "equal" -%>
28+
<%= sub_case["expected"] ? "assert" : "refute" %>_equal set1, set2
29+
<%- elsif sub_case["property"] == "intersection" -%>
30+
expected = CustomSet.new <%= sub_case["expected"] %>
31+
assert_equal expected, set1.intersection(set2)
32+
<%- elsif sub_case["property"] == "difference" -%>
33+
expected = CustomSet.new <%= sub_case["expected"] %>
34+
assert_equal expected, set1.difference(set2)
35+
<%- elsif sub_case["property"] == "union" -%>
36+
expected = CustomSet.new <%= sub_case["expected"] %>
37+
assert_equal expected, set1.union(set2)
38+
<%- end -%>
39+
<% end %>
40+
end
41+
<% end %>
42+
<% end %>
43+
end

0 commit comments

Comments
 (0)