Skip to content

Commit

Permalink
ruby/circular-buffer: 1st iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
vpayno committed Oct 30, 2023
1 parent 6ecba24 commit 8ff8b9f
Show file tree
Hide file tree
Showing 9 changed files with 557 additions and 16 deletions.
1 change: 1 addition & 0 deletions ruby/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@
- [allergies](./allergies/README.md)
- [simple-cipher](./simple-cipher/README.md)
- [clock](./clock/README.md)
- [circular-buffer](./circular-buffer/README.md)
7 changes: 6 additions & 1 deletion ruby/circular-buffer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ Because there is space available, if the client again uses overwrite to store C

### Based on

Wikipedia - https://en.wikipedia.org/wiki/Circular_buffer
Wikipedia - https://en.wikipedia.org/wiki/Circular_buffer

### My Solution

- [my solution](./circular_buffer.rb)
- [run-tests](./run-tests-ruby.txt)
65 changes: 59 additions & 6 deletions ruby/circular-buffer/circular_buffer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
=begin
Write your code for the 'Circular Buffer' exercise in this file. Make the tests in
`circular_buffer_test.rb` pass.
# frozen_string_literal: false

To get started with TDD, see the `README.md` file in your
`ruby/circular-buffer` directory.
=end
# https://exercism.org/tracks/ruby/exercises/circular-buffer
# Circular Buffer exercise
class CircularBuffer
def initialize(capacity = 1)
@capacity = capacity
@buffer = Array.new(@capacity, nil)
@read_ptr = 0
@write_ptr = 0
end

def clear
@read_ptr = 0
@write_ptr = 0
end

def read
raise BufferEmptyException if @read_ptr == @write_ptr

data = @buffer[@read_ptr]
@read_ptr = (@read_ptr + 1) % (@capacity + 1)

data
end

def write(data)
new_write_ptr = (@write_ptr + 1) % (@capacity + 1)
raise BufferFullException if new_write_ptr == @read_ptr

@buffer[@write_ptr] = data
@write_ptr = new_write_ptr
end

def write!(data)
new_write_ptr = (@write_ptr + 1) % (@capacity + 1)
@read_ptr = (@read_ptr + 1) % (@capacity + 1) if new_write_ptr == @read_ptr

@buffer[@write_ptr] = data
@write_ptr = new_write_ptr
end

def to_s
output = []
output.push(" buffer: #{@buffer}")
output.push("write_ptr: #{@write_ptr}")
output.push(" read_ptr: #{@read_ptr}")
output.push(" capacity: #{@capacity}")

output.join("\n")
end

# Raised when the buffer size is zero
class BufferEmptyException < StandardError
end

# Raised when the buffer is full
class BufferFullException < StandardError
end
end
42 changes: 33 additions & 9 deletions ruby/circular-buffer/circular_buffer_test.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# frozen_string_literal: false

# https://github.com/simplecov-ruby/simplecov
require 'simplecov'

# https://about.codecov.io/blog/getting-started-with-code-coverage-for-ruby/
require 'simplecov-cobertura'
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter

# line coverage
SimpleCov.start if ENV['COVERAGE'] != 'branch'

# branch coverage
if ENV['COVERAGE'] == 'branch'
SimpleCov.start do
enable_coverage :branch
primary_coverage :branch
end
end

# name the test file/group
SimpleCov.command_name 'test:exercism'

# original exercism tests
require 'minitest/autorun'
require_relative 'circular_buffer'

Expand All @@ -8,15 +32,15 @@ def test_read_empty_buffer_throws_buffer_empty_exception
end

def test_write_and_read_back_one_item
skip
# skip
buffer = CircularBuffer.new(1)
buffer.write '1'
assert_equal '1', buffer.read
assert_raises(CircularBuffer::BufferEmptyException) { buffer.read }
end

def test_write_and_read_back_multiple_items
skip
# skip
buffer = CircularBuffer.new(2)
buffer.write '1'
buffer.write '2'
Expand All @@ -26,7 +50,7 @@ def test_write_and_read_back_multiple_items
end

def test_clearing_buffer
skip
# skip
buffer = CircularBuffer.new(3)
('1'..'3').each { |i| buffer.write i }
buffer.clear
Expand All @@ -39,7 +63,7 @@ def test_clearing_buffer
end

def test_alternate_write_and_read
skip
# skip
buffer = CircularBuffer.new(2)
buffer.write '1'
assert_equal '1', buffer.read
Expand All @@ -48,7 +72,7 @@ def test_alternate_write_and_read
end

def test_reads_back_oldest_item
skip
# skip
buffer = CircularBuffer.new(3)
buffer.write '1'
buffer.write '2'
Expand All @@ -59,15 +83,15 @@ def test_reads_back_oldest_item
end

def test_writing_to_a_full_buffer_throws_an_exception
skip
# skip
buffer = CircularBuffer.new(2)
buffer.write '1'
buffer.write '2'
assert_raises(CircularBuffer::BufferFullException) { buffer.write 'A' }
end

def test_overwriting_oldest_item_in_a_full_buffer
skip
# skip
buffer = CircularBuffer.new(2)
buffer.write '1'
buffer.write '2'
Expand All @@ -78,7 +102,7 @@ def test_overwriting_oldest_item_in_a_full_buffer
end

def test_forced_writes_to_non_full_buffer_should_behave_like_writes
skip
# skip
buffer = CircularBuffer.new(2)
buffer.write '1'
buffer.write! '2'
Expand All @@ -88,7 +112,7 @@ def test_forced_writes_to_non_full_buffer_should_behave_like_writes
end

def test_alternate_read_and_write_into_buffer_overflow
skip
# skip
buffer = CircularBuffer.new(5)
('1'..'3').each { |i| buffer.write i }
buffer.read
Expand Down
5 changes: 5 additions & 0 deletions ruby/circular-buffer/coverage/.last_run.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"result": {
"line": 81.81
}
}
71 changes: 71 additions & 0 deletions ruby/circular-buffer/coverage/.resultset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"test:exercism": {
"coverage": {
"/home/vpayno/git_vpayno/exercism-workspace/ruby/circular-buffer/circular_buffer.rb": {
"lines": [
null,
null,
null,
null,
1,
1,
10,
10,
10,
10,
null,
null,
1,
1,
1,
null,
null,
1,
29,
null,
22,
22,
null,
22,
null,
null,
1,
28,
28,
null,
27,
27,
null,
null,
1,
4,
4,
null,
4,
4,
null,
null,
1,
0,
0,
0,
0,
0,
null,
0,
null,
null,
null,
1,
null,
null,
null,
1,
null,
null
]
}
},
"timestamp": 1698644242
}
}
Empty file.
52 changes: 52 additions & 0 deletions ruby/circular-buffer/coverage/coverage.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version='1.0'?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<!-- Generated by simplecov-cobertura version 2.1.0 (https://github.com/dashingrocket/simplecov-cobertura) -->
<coverage line-rate="0.82" lines-covered="27" lines-valid="33" complexity="0" version="0" timestamp="1698644242">
<sources>
<source>/home/vpayno/git_vpayno/exercism-workspace/ruby/circular-buffer</source>
</sources>
<packages>
<package name="circular-buffer" line-rate="0.82" complexity="0">
<classes>
<class name="circular_buffer" filename="circular_buffer.rb" line-rate="0.82" complexity="0">
<methods/>
<lines>
<line number="5" hits="1"/>
<line number="6" hits="1"/>
<line number="7" hits="10"/>
<line number="8" hits="10"/>
<line number="9" hits="10"/>
<line number="10" hits="10"/>
<line number="13" hits="1"/>
<line number="14" hits="1"/>
<line number="15" hits="1"/>
<line number="18" hits="1"/>
<line number="19" hits="29"/>
<line number="21" hits="22"/>
<line number="22" hits="22"/>
<line number="24" hits="22"/>
<line number="27" hits="1"/>
<line number="28" hits="28"/>
<line number="29" hits="28"/>
<line number="31" hits="27"/>
<line number="32" hits="27"/>
<line number="35" hits="1"/>
<line number="36" hits="4"/>
<line number="37" hits="4"/>
<line number="39" hits="4"/>
<line number="40" hits="4"/>
<line number="43" hits="1"/>
<line number="44" hits="0"/>
<line number="45" hits="0"/>
<line number="46" hits="0"/>
<line number="47" hits="0"/>
<line number="48" hits="0"/>
<line number="50" hits="0"/>
<line number="54" hits="1"/>
<line number="58" hits="1"/>
</lines>
</class>
</classes>
</package>
</packages>
</coverage>
Loading

0 comments on commit 8ff8b9f

Please sign in to comment.