Skip to content

Instantly share code, notes, and snippets.

@Aupajo
Last active March 22, 2017 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Aupajo/abb53ae83341f911920067d1f5d53a69 to your computer and use it in GitHub Desktop.
Save Aupajo/abb53ae83341f911920067d1f5d53a69 to your computer and use it in GitHub Desktop.
class BufferedJsonArray
ClosedError = Class.new(StandardError)
def initialize(target_buffer)
@target_buffer = target_buffer
@internal_buffer = "["
@closed = false
@first_entry = true
end
def <<(value)
append "," unless first_entry?
append value.to_json
flush
end
def close
append "]"
flush
closed!
end
private
def append(string)
fail ClosedError, "Buffer has already been closed" if closed?
@first_entry = false
@internal_buffer << string
end
def flush
@target_buffer << @internal_buffer
@internal_buffer = ""
end
def first_entry?
@first_entry
end
def closed!
@closed = true
end
def closed?
@closed
end
end
require 'rails_helper'
RSpec.describe BufferedJsonArray do
let(:stream) { "" }
let(:buffered) { BufferedJsonArray.new(stream) }
it "can successively yields JSON in an array" do
expect { buffered << 'A' }.to change { stream }.from('').to(%{["A"})
expect { buffered << 'B' }.to change { stream }.to(%{["A","B"})
expect { buffered << 'C' }.to change { stream }.to(%{["A","B","C"})
expect { buffered.close }.to change { stream }.to(%{["A","B","C"]})
end
it "can yield a valid empty array" do
buffered.close
expect(stream).to eq "[]"
end
it "cannot be written after closing" do
buffered.close
expect { buffered << "value" }.to raise_error(BufferedJsonArray::ClosedError)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment