Adjust Snapshot#crop to work on already optimized lines

openid
Marcin Kulik 11 years ago
parent 22f076a366
commit 82fa03863d

@ -3,21 +3,11 @@ class SnapshotDecorator < ApplicationDecorator
delegate_all
def lines
(0...height).map { |line_no| line(line_no) }
model.lines.map { |line| decorate_cells(line) }
end
private
def line(line_no)
line = (0...width).map { |column_no| model.cell(column_no, line_no) }
decorate_cells(optimize_line(line))
end
def optimize_line(line)
LineOptimizer.new.optimize(line)
end
def decorate_cells(cells)
cells.map { |cell| CellDecorator.new(cell) }
end

@ -2,6 +2,8 @@ class Cell
attr_reader :text, :brush
delegate :size, :to => :text
def initialize(text, brush)
@text = text
@brush = brush
@ -15,6 +17,10 @@ class Cell
text == other.text && brush == other.brush
end
def [](*args)
self.class.new(text[*args], brush)
end
def as_json(*)
[text, brush.as_json]
end

@ -1,23 +1,16 @@
class Grid
attr_reader :width, :height
attr_reader :width, :height, :lines
def initialize(lines)
@lines = lines
@width = lines.first && lines.first.size || 0
@width = lines.first && lines.first.sum(&:size) || 0
@height = lines.size
end
def ==(other)
lines == other.lines
end
def cell(x, y)
lines[y][x]
end
def crop(x, y, width, height)
cropped_lines = lines[y...y+height].map { |line| line[x...x+width] }
cropped_lines = lines[y...y+height].map { |line| crop_line(line, x, width) }
self.class.new(cropped_lines)
end
@ -33,8 +26,25 @@ class Grid
lines.as_json
end
protected
private
def crop_line(line, x, width)
n = 0
cells = []
attr_reader :lines
line.each do |cell|
if n <= x && x < n + cell.size
cells << cell[x-n...x-n+width]
elsif x < n && x + width >= n + cell.size
cells << cell
elsif n < x + width && x + width < n + cell.size
cells << cell[0...x+width-n]
end
n += cell.size
end
cells
end
end

@ -1,25 +0,0 @@
class LineOptimizer
def optimize(line)
return [] if line.empty?
text = [line[0].text]
brush = line[0].brush
cells = []
line[1..-1].each do |cell|
if cell.brush == brush
text << cell.text
else
cells << Cell.new(text.join, brush)
text, brush = [cell.text], cell.brush
end
end
cells << Cell.new(text.join, brush)
cells
end
end

@ -3,23 +3,13 @@ require 'spec_helper'
describe SnapshotDecorator do
let(:decorator) { described_class.new(snapshot) }
let(:snapshot) { double('snapshot', :width => 2, :height => 2) }
let(:optimizer) { double('optimizer') }
let(:cells) { [
[:a, :b],
[:c, :d]
] }
let(:snapshot) { double('snapshot', :width => 2, :height => 2, :lines => lines) }
let(:lines) { [ [:ab], [:c, :d] ] }
describe '#lines' do
subject { decorator.lines }
before do
allow(snapshot).to receive(:cell) { |x, y| cells[y][x] }
allow(LineOptimizer).to receive(:new) { optimizer }
allow(optimizer).to receive(:optimize).with([:a, :b]) { [:ab] }
allow(optimizer).to receive(:optimize).with([:c, :d]) { [:c, :d] }
allow(CellDecorator).to receive(:new).with(:ab) { :AB }
allow(CellDecorator).to receive(:new).with(:c) { :C }
allow(CellDecorator).to receive(:new).with(:d) { :D }

@ -59,6 +59,16 @@ describe Cell do
end
end
describe '#[]' do
let(:cell) { described_class.new('abcdef', brush) }
subject { cell[2..4] }
it 'returns new cell with the cropped text and the same brush' do
expect(subject).to eq(Cell.new('cde', brush))
end
end
describe '#as_json' do
subject { cell.as_json }

@ -5,37 +5,18 @@ describe Grid do
let(:grid) { described_class.new(data) }
let(:data) { [
[:a, :b, :c],
[:d, :e, :f],
[:g, :h, :i],
[:j, :k, :l]
%w[a b c ć],
%w[de ff],
%w[ghiî],
%w[j k l m]
] }
describe '#==' do
let(:grid) { described_class.new(grid_lines) }
let(:other) { described_class.new(other_lines) }
subject { grid == other }
context "when lines are equal" do
let(:grid_lines) { [:a] }
let(:other_lines) { [:a] }
it { should be(true) }
end
context "when lines are different" do
let(:grid_lines) { [:a] }
let(:other_lines) { [:b] }
it { should be(false) }
end
end
describe '#width' do
let(:data) { [ %w[a bc def] ] }
subject { grid.width }
it { should eq(3) }
it { should eq(6) }
end
describe '#height' do
@ -44,18 +25,12 @@ describe Grid do
it { should eq(4) }
end
describe '#cell' do
it 'returns item at given x and y position' do
expect(grid.cell(0, 0)).to eq(:a)
expect(grid.cell(1, 2)).to eq(:h)
expect(grid.cell(2, 3)).to eq(:l)
end
end
describe '#crop' do
subject { grid.crop(1, 0, 2, 3) }
let(:expected) { described_class.new([%w[e f], %w[hi], %w[k l]]).lines }
it { should eq(described_class.new([[:b, :c], [:e, :f], [:h, :i]])) }
it 'crops the lines properly' do
expect(grid.crop(1, 1, 2, 3).lines).to eq(expected)
end
end
describe '#diff' do
@ -88,7 +63,7 @@ describe Grid do
describe '#as_json' do
subject { grid.as_json }
it { should eq([%w[a b c], %w[d e f], %w[g h i], %w[j k l]]) }
it { should eq([%w[a b c ć], %w[de ff], %w[ghiî], %w[j k l m]]) }
end
end

@ -4,10 +4,10 @@ describe Snapshot do
let(:snapshot) { described_class.build(data) }
let(:data) { [
[['a', fg: 1], ['b', fg: 2]],
[['a', fg: 3], ['b', fg: 4]],
[['a', fg: 5], ['b', fg: 6]],
[[' ', {}] , ['' , {}]]
[['a', fg: 1], ['b', fg: 2]],
[['ab', fg: 3] ],
[['a', fg: 5], ['b', fg: 6]],
[[' ', {}] , ['' , {}]]
] }
describe '#thumbnail' do

@ -1,29 +0,0 @@
require 'spec_helper'
describe LineOptimizer do
let(:line_optimizer) { described_class.new }
def brush(attrs)
Brush.new(attrs)
end
describe '#optimize' do
let(:line) { [
Cell.new('a', brush(fg: 1)),
Cell.new('b', brush(fg: 1)),
Cell.new('c', brush(fg: 2)),
Cell.new('d', brush(fg: 3)),
Cell.new('e', brush(fg: 3))
] }
subject { line_optimizer.optimize(line) }
it { should eq([
Cell.new('ab', brush(fg: 1)),
Cell.new('c', brush(fg: 2)),
Cell.new('de', brush(fg: 3))
]) }
end
end
Loading…
Cancel
Save