Last active
November 13, 2017 21:45
-
-
Save tomphp/3d6e5ab5b5ee9db9f1f4b560e3a0b2bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSpec.describe 'acceptance test' do | |
xit 'works' do | |
runner = CommandRunner.new(Tokenizer.new) | |
expect(runner.run( | |
'I 5 5', | |
'C 1', | |
'V 2 5 3 4', | |
'H 5 1 4 3', | |
'P 4 2 2', | |
'S' | |
)).to eq([ | |
'11111', | |
'11421', | |
'11411', | |
'11411', | |
'33331' | |
]) | |
end | |
end | |
class Tokenizer | |
INITIALIZE_REGEX = /^I (\d+) (\d+)$/ | |
CLEAR_REGEX = /^C(?: (\d+))?$/ | |
SET_PIXEL_REGEX = /^P (\d+) (\d+) (\d+)$/ | |
VLINE_REGEX = /^V (\d+) (\d+) (\d+) (\d+)$/ | |
SHOW = /^S$/ | |
def tokenize(commands) | |
case commands | |
when INITIALIZE_REGEX | |
(width, height) = commands.match(INITIALIZE_REGEX).captures | |
{ type: :initialize, width: width.to_i, height: height.to_i } | |
when CLEAR_REGEX | |
colour = commands.match(CLEAR_REGEX).captures[0] | |
{ type: :clear, value: colour.to_i || 0 } | |
when SET_PIXEL_REGEX | |
(x, y, colour) = commands.match(SET_PIXEL_REGEX).captures | |
{ type: :set_pixel, x: x.to_i, y: y.to_i, colour: colour.to_i } | |
when VLINE_REGEX | |
(x, y, l, colour) = commands.match(SET_PIXEL_REGEX).captures | |
{ type: :vline, x: x.to_i, y: y.to_i, colour: colour.to_i } | |
when SHOW | |
{ type: :show } | |
end | |
end | |
end | |
RSpec.describe Tokenizer do | |
describe '#tokenize' do | |
it 'tokenizes initialize' do | |
expect(subject.tokenize('I 2 4')).to eq(type: :initialize, width: 2, height: 4) | |
expect(subject.tokenize('I 3 7')).to eq(type: :initialize, width: 3, height: 7) | |
end | |
it 'tokenizes clear with value' do | |
expect(subject.tokenize('C 11')).to eq(type: :clear, value: 11) | |
expect(subject.tokenize('C 101')).to eq(type: :clear, value: 101) | |
end | |
it 'tokenizes clear without value' do | |
expect(subject.tokenize('C')).to eq(type: :clear, value: 0) | |
end | |
it 'tokenizes set pixed' do | |
expect(subject.tokenize('P 5 3 9')).to eq(type: :set_pixel, x: 5, y: 3, colour: 9) | |
expect(subject.tokenize('P 6 4 10')).to eq(type: :set_pixel, x: 6, y: 4, colour: 10) | |
end | |
it 'tokenize show' do | |
expect(subject.tokenize('S')).to eq(type: :show) | |
end | |
end | |
end | |
class CommandRunner | |
def run(*commands) | |
tokenizer = Tokenizer.new | |
image = nil | |
commands.each do |cmd| | |
token = tokenizer.tokenize(cmd) | |
case token[:type] | |
when :initialize | |
image = Image.new(token[:width], token[:height]) | |
when :clear | |
image.clear(token[:value]) | |
when :set_pixel | |
image.set_pixel(token[:x], token[:y], token[:colour]) | |
end | |
end | |
image.show | |
end | |
end | |
RSpec.describe CommandRunner do | |
subject { described_class.new } | |
let(:result) { 'rendered' } | |
let(:image) { spy('image', show: result) } | |
describe '#run' do | |
before do | |
allow(Image).to receive(:new).and_return(image) | |
end | |
it 'creates an image' do | |
subject.run('I 1 4') | |
expect(Image).to have_received(:new).with(1, 4) | |
end | |
it 'clears the image' do | |
subject.run('I 1 4', 'C', 'S') | |
expect(image).to have_received(:clear).with(0) | |
end | |
it 'clears the image with colour' do | |
subject.run('I 1 4', 'C 4', 'S') | |
expect(image).to have_received(:clear).with(4) | |
end | |
it 'sets a pixel ' do | |
subject.run('I 1 4', 'P 1 2 3', 'S') | |
expect(image).to have_received(:set_pixel).with(1, 2, 3) | |
end | |
it 'sets a different pixel ' do | |
subject.run('I 1 4', 'P 2 3 4', 'S') | |
expect(image).to have_received(:set_pixel).with(2, 3, 4) | |
end | |
it 'returns shows the image' do | |
expect(subject.run('I 1 4', 'S')).to eq(result) | |
end | |
end | |
end | |
class Image | |
def initialize(width, height) | |
@width = width | |
@height = height | |
@image = @height.times.map { @width.times.map { 0 } } | |
end | |
def clear(colour) | |
@image = @height.times.map { @width.times.map { colour } } | |
end | |
def set_pixel(x, y, colour) | |
@image[x-1][y-1] = colour | |
end | |
def show | |
@image | |
end | |
end | |
RSpec.describe Image do | |
it 'shows an empty image' do | |
expect(described_class.new(1, 2).show).to eq([[0], [0]]) | |
expect(described_class.new(2, 1).show).to eq([[0, 0]]) | |
end | |
context 'with 2 x 3 image' do | |
subject { Image.new(2, 3) } | |
it 'sets a pixel' do | |
subject.set_pixel(1, 2, 3) | |
expect(subject.show).to eq([ | |
[0, 3], | |
[0, 0], | |
[0, 0] | |
]) | |
end | |
it 'clears' do | |
subject.clear(5) | |
expect(subject.show).to eq([ | |
[5, 5], | |
[5, 5], | |
[5, 5] | |
]) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment