diff --git a/assets/scripts/lib/travis/chunk_buffer.coffee b/assets/scripts/lib/travis/chunk_buffer.coffee new file mode 100644 index 00000000..55379b48 --- /dev/null +++ b/assets/scripts/lib/travis/chunk_buffer.coffee @@ -0,0 +1,43 @@ +Travis.ChunkBuffer = Em.ArrayProxy.extend + timeout: 15000 + start: 0 + next: 0 + + init: -> + @_super.apply this, arguments + + if @get('content.length') + @get('queue.content').pushObjects @get('content').toArray() + + arrangedContent: (-> + [] + ).property('content') + + queue: (-> + Em.ArrayProxy.create(Em.SortableMixin, + content: [] + sortProperties: ['number'] + sortAscending: true + ) + ).property() + + contentArrayDidChange: (array, index, removedCount, addedCount) -> + console.log 'content array did change' + @_super.apply this, arguments + + if addedCount + queue = @get('queue.content') + queue.pushObjects array.slice(index, index + addedCount) + @check() + + check: -> + queue = @get('queue') + next = @get('next') + + arrangedContent = @get('arrangedContent') + + while queue.get('firstObject.number') == next + arrangedContent.pushObject queue.shiftObject().get('content') + next += 1 + + @set('next', next) diff --git a/assets/scripts/spec/unit/chunk_buffer_spec.coffee b/assets/scripts/spec/unit/chunk_buffer_spec.coffee new file mode 100644 index 00000000..fca3cbac --- /dev/null +++ b/assets/scripts/spec/unit/chunk_buffer_spec.coffee @@ -0,0 +1,52 @@ +createChunk = (number, content) -> + Em.Object.create(number: number, content: content) + +describe 'Travis.ChunkBuffer', -> + it 'waits for parts to be in order before revealing them', -> + content = [] + buffer = Travis.ChunkBuffer.create(content: content) + + content.pushObject createChunk(2, "baz") + content.pushObject createChunk(1, "bar") + + expect(buffer.get('length')).toEqual(0) + + content.pushObject createChunk(0, "foo") + + expect(buffer.get('length')).toEqual(3) + + expect(buffer.toArray()).toEqual(['foo', 'bar', 'baz']) + + it 'ignores a part if it fails to be delivered within timeout', -> + expect 4 + + content = [] + buffer = Travis.ChunkBuffer.create(content: content, timeout: 10) + + content.pushObject createChunk(2, "baz") + + expect(buffer.get('length')).toEqual(0) + + content.pushObject createChunk(0, "foo") + + expect(buffer.get('length')).toEqual(1) + + stop() + setTimeout( (-> + expect(buffer.get('length')).toEqual(2) + expect(buffer.toArray()).toEqual(['foo', 'bar', 'baz']) + ), 20) + + it 'works correctly when parts are passed as content', -> + content = [createChunk(1, 'bar')] + + buffer = Travis.ChunkBuffer.create(content: content) + + expect(buffer.get('length')).toEqual(0) + + content.pushObject createChunk(0, "foo") + + expect(buffer.get('length')).toEqual(2) + expect(buffer.toArray()).toEqual(['foo', 'bar']) + +