Make Stdout provide data in chunks

This commit is contained in:
Marcin Kulik 2013-08-13 19:27:02 +02:00
parent fa4c5e4664
commit 6c8dbf4173
6 changed files with 40 additions and 59 deletions

View File

@ -56,17 +56,7 @@ class Asciicast < ActiveRecord::Base
end end
def stdout def stdout
@stdout ||= Stdout.new(read_stdout_data, read_stdout_timing) @stdout ||= Stdout.new(stdout_data, stdout_timing)
end
private
def read_stdout_data
stdout_data.decompressed
end
def read_stdout_timing
TimingParser.parse(stdout_timing.decompressed)
end end
end end

View File

@ -1,40 +1,30 @@
class Stdout class Stdout
include Enumerable include Enumerable
attr_reader :data, :timing attr_reader :data_file, :timing_file
def initialize(data, timing) def initialize(data_file, timing_file)
@data = data @data_file = data_file
@timing = timing @timing_file = timing_file
end end
def each def each
offset = 0 File.open(data_file.decompressed_path, 'rb') do |file|
File.foreach(timing_file.decompressed_path) do |line|
timing.each do |line| delay, size = TimingParser.parse_line(line)
delay, size = line yield(delay, file.read(size).force_encoding('utf-8'))
yield(delay, bytes[offset...offset+size]) end
offset += size
end end
end end
def bytes_until(seconds) def each_until(seconds)
bytes = []
time = 0 time = 0
each do |delay, frame_bytes| each do |delay, frame_data|
time += delay time += delay
break if time > seconds break if time > seconds
bytes.concat(frame_bytes) yield(delay, frame_data)
end end
bytes
end
private
def bytes
@bytes ||= data.bytes
end end
end end

1
spec/fixtures/stdout.decompressed vendored Normal file
View File

@ -0,0 +1 @@
foobarbazquxżółć

View File

@ -0,0 +1,3 @@
0.5 6
1.0 7
2.0 7

View File

@ -84,17 +84,21 @@ describe Asciicast do
end end
describe '#stdout' do describe '#stdout' do
let(:asciicast) { stub_model(Asciicast) }
let(:data_file) { double('data_file') }
let(:timing_file) { double('timing_file') }
let(:stdout) { double('stdout') } let(:stdout) { double('stdout') }
before do before do
allow(asciicast.stdout_data).to receive(:decompressed) { 'foo' } allow(asciicast).to receive(:stdout_data) { data_file }
allow(asciicast.stdout_timing).to receive(:decompressed) { '123.0 45' } allow(asciicast).to receive(:stdout_timing) { timing_file }
allow(Stdout).to receive(:new) { stdout } allow(Stdout).to receive(:new) { stdout }
end end
it 'creates a new Stdout instance' do it 'creates a new Stdout instance' do
asciicast.stdout asciicast.stdout
expect(Stdout).to have_received(:new).with('foo', [[123.0, 45]])
expect(Stdout).to have_received(:new).with(data_file, timing_file)
end end
it 'returns created Stdout instance' do it 'returns created Stdout instance' do

View File

@ -3,31 +3,24 @@
require 'spec_helper' require 'spec_helper'
describe Stdout do describe Stdout do
let(:stdout) { Stdout.new(data, timing) } let(:stdout) { Stdout.new(data_file, timing_file) }
let(:data) { 'foobarbazquxżółć' } let(:data_file) { double('data_file', :decompressed_path => 'spec/fixtures/stdout.decompressed') }
let(:timing) { [[0.5, 6], [1.0, 7], [2.0, 7]] } let(:timing_file) { double('timing_file', :decompressed_path => 'spec/fixtures/stdout.time.decompressed') }
describe '#bytes_until' do
subject { stdout.bytes_until(1.7) }
it { should eq([102, 111, 111, 98, 97, 114, 98, 97, 122, 113, 117, 120, 197]) }
end
describe '#each' do describe '#each' do
it 'yields for each frame with delay and frame bytes' do it 'yields for each frame with delay and data' do
frames = [] expect { |b| stdout.each(&b) }.
stdout.each do |delay, bytes| to yield_successive_args([0.5, 'foobar'],
frames << [delay, bytes] [1.0, "bazqux\xC5"],
end [2.0, "\xBCółć"])
expect(frames[0][0]).to eq(0.5)
expect(frames[0][1]).to eq([102, 111, 111, 98, 97, 114])
expect(frames[1][0]).to eq(1.0)
expect(frames[1][1]).to eq([98, 97, 122, 113, 117, 120, 197])
expect(frames[2][0]).to eq(2.0)
expect(frames[2][1]).to eq([188, 195, 179, 197, 130, 196, 135])
end end
end end
describe '#each_until' do
it 'yields for each frame with delay and data until given time (in seconds)' do
expect { |b| stdout.each_until(1.7, &b) }.
to yield_successive_args([0.5, 'foobar'], [1.0, "bazqux\xC5"])
end
end
end end