mirror of
https://github.com/overleaf/overleaf.git
synced 2025-03-30 23:43:53 +00:00
Don't trip up over empty ops
This commit is contained in:
parent
bd4bb3d3cf
commit
22e3aac5b0
4 changed files with 171 additions and 6 deletions
|
@ -2,6 +2,8 @@ strInject = (s1, pos, s2) -> s1[...pos] + s2 + s1[pos..]
|
|||
strRemove = (s1, pos, length) -> s1[...pos] + s1[(pos + length)..]
|
||||
|
||||
module.exports = UpdateCompressor =
|
||||
NOOP: "noop"
|
||||
|
||||
# Updates come from the doc updater in format
|
||||
# {
|
||||
# op: [ { ... op1 ... }, { ... op2 ... } ]
|
||||
|
@ -19,14 +21,23 @@ module.exports = UpdateCompressor =
|
|||
convertToSingleOpUpdates: (updates) ->
|
||||
splitUpdates = []
|
||||
for update in updates
|
||||
for op in update.op
|
||||
if update.op.length == 0
|
||||
splitUpdates.push
|
||||
op: op
|
||||
op: UpdateCompressor.NOOP
|
||||
meta:
|
||||
start_ts: update.meta.start_ts or update.meta.ts
|
||||
end_ts: update.meta.end_ts or update.meta.ts
|
||||
user_id: update.meta.user_id
|
||||
v: update.v
|
||||
else
|
||||
for op in update.op
|
||||
splitUpdates.push
|
||||
op: op
|
||||
meta:
|
||||
start_ts: update.meta.start_ts or update.meta.ts
|
||||
end_ts: update.meta.end_ts or update.meta.ts
|
||||
user_id: update.meta.user_id
|
||||
v: update.v
|
||||
return splitUpdates
|
||||
|
||||
concatUpdatesWithSameVersion: (updates) ->
|
||||
|
@ -34,12 +45,14 @@ module.exports = UpdateCompressor =
|
|||
for update in updates
|
||||
lastUpdate = concattedUpdates[concattedUpdates.length - 1]
|
||||
if lastUpdate? and lastUpdate.v == update.v
|
||||
lastUpdate.op.push update.op
|
||||
lastUpdate.op.push update.op unless update.op == UpdateCompressor.NOOP
|
||||
else
|
||||
concattedUpdates.push
|
||||
op: [ update.op ]
|
||||
nextUpdate =
|
||||
op: []
|
||||
meta: update.meta
|
||||
v: update.v
|
||||
nextUpdate.op.push update.op unless update.op == UpdateCompressor.NOOP
|
||||
concattedUpdates.push nextUpdate
|
||||
return concattedUpdates
|
||||
|
||||
compressRawUpdates: (lastPreviousUpdate, rawUpdates) ->
|
||||
|
|
|
@ -194,3 +194,35 @@ describe "Appending doc ops to the history", ->
|
|||
expect(@updates[0].v).to.equal 3
|
||||
expect(@updates[1].v).to.equal 4
|
||||
|
||||
describe "when there is a no-op update", ->
|
||||
before (done) ->
|
||||
@project_id = ObjectId().toString()
|
||||
@doc_id = ObjectId().toString()
|
||||
@user_id = ObjectId().toString()
|
||||
oneDay = 24 * 60 * 60 * 1000
|
||||
TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
|
||||
op: []
|
||||
meta: { ts: Date.now(), user_id: @user_id }
|
||||
v: 3
|
||||
}, {
|
||||
op: [{ i: "foo", p: 3 }]
|
||||
meta: { ts: Date.now() + oneDay, user_id: @user_id }
|
||||
v: 4
|
||||
}], (error) =>
|
||||
throw error if error?
|
||||
TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
it "should insert the compressed no-op into mongo", ->
|
||||
expect(@updates[0].op).to.deep.equal []
|
||||
|
||||
|
||||
it "should insert the compressed next update into mongo", ->
|
||||
expect(@updates[1].op).to.deep.equal [{
|
||||
p: 3, i: "foo"
|
||||
}]
|
||||
|
||||
it "should insert the correct version numbers into mongo", ->
|
||||
expect(@updates[0].v).to.equal 3
|
||||
expect(@updates[1].v).to.equal 4
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
sinon = require "sinon"
|
||||
chai = require("chai")
|
||||
chai.should()
|
||||
expect = chai.expect
|
||||
mongojs = require "../../../app/js/mongojs"
|
||||
ObjectId = mongojs.ObjectId
|
||||
Settings = require "settings-sharelatex"
|
||||
request = require "request"
|
||||
rclient = require("redis").createClient() # Only works locally for now
|
||||
|
||||
TrackChangesClient = require "./helpers/TrackChangesClient"
|
||||
|
||||
describe "Flushing updates", ->
|
||||
describe "flushing a doc's updates", ->
|
||||
before (done) ->
|
||||
@project_id = ObjectId().toString()
|
||||
@doc_id = ObjectId().toString()
|
||||
@user_id = ObjectId().toString()
|
||||
TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
|
||||
op: [{ i: "f", p: 3 }]
|
||||
meta: { ts: Date.now(), user_id: @user_id }
|
||||
v: 3
|
||||
}], (error) =>
|
||||
throw error if error?
|
||||
TrackChangesClient.flushDoc @project_id, @doc_id, (error) ->
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
it "should flush the op into mongo", (done) ->
|
||||
TrackChangesClient.getCompressedUpdates @doc_id, (error, updates) ->
|
||||
expect(updates[0].op).to.deep.equal [{
|
||||
p: 3, i: "f"
|
||||
}]
|
||||
done()
|
||||
|
||||
describe "flushing a project's updates", ->
|
||||
before (done) ->
|
||||
@project_id = ObjectId().toString()
|
||||
@doc_id = ObjectId().toString()
|
||||
@user_id = ObjectId().toString()
|
||||
TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
|
||||
op: [{ i: "f", p: 3 }]
|
||||
meta: { ts: Date.now(), user_id: @user_id }
|
||||
v: 3
|
||||
}], (error) =>
|
||||
throw error if error?
|
||||
TrackChangesClient.flushProject @project_id, (error) ->
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
it "should flush the op into mongo", (done) ->
|
||||
TrackChangesClient.getCompressedUpdates @doc_id, (error, updates) ->
|
||||
expect(updates[0].op).to.deep.equal [{
|
||||
p: 3, i: "f"
|
||||
}]
|
||||
done()
|
|
@ -38,6 +38,18 @@ describe "UpdateCompressor", ->
|
|||
v: 43
|
||||
}]
|
||||
|
||||
it "should return no-op updates when the op list is empty", ->
|
||||
expect(@UpdateCompressor.convertToSingleOpUpdates [{
|
||||
op: []
|
||||
meta: { ts: @ts1, user_id: @user_id }
|
||||
v: 42
|
||||
}])
|
||||
.to.deep.equal [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: { start_ts: @ts1, end_ts: @ts1, user_id: @user_id },
|
||||
v: 42
|
||||
}]
|
||||
|
||||
describe "concatUpdatesWithSameVersion", ->
|
||||
it "should concat updates with the same version", ->
|
||||
expect(@UpdateCompressor.concatUpdatesWithSameVersion [{
|
||||
|
@ -63,6 +75,18 @@ describe "UpdateCompressor", ->
|
|||
v: 43
|
||||
}]
|
||||
|
||||
it "should turn a noop into an empty op", ->
|
||||
expect(@UpdateCompressor.concatUpdatesWithSameVersion [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: { start_ts: @ts1, end_ts: @ts1, user_id: @user_id }
|
||||
v: 42
|
||||
}])
|
||||
.to.deep.equal [{
|
||||
op: []
|
||||
meta: { start_ts: @ts1, end_ts: @ts1, user_id: @user_id }
|
||||
v: 42
|
||||
}]
|
||||
|
||||
describe "compress", ->
|
||||
describe "insert - insert", ->
|
||||
it "should append one insert to the other", ->
|
||||
|
@ -239,4 +263,44 @@ describe "UpdateCompressor", ->
|
|||
v: 43
|
||||
}]
|
||||
|
||||
|
||||
describe "noop - insert", ->
|
||||
it "should leave them untouched", ->
|
||||
expect(@UpdateCompressor.compressUpdates [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: ts: @ts1, user_id: @user_id
|
||||
v: 42
|
||||
}, {
|
||||
op: { p: 6, i: "bar" }
|
||||
meta: ts: @ts1, user_id: @user_id
|
||||
v: 43
|
||||
}])
|
||||
.to.deep.equal [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: start_ts: @ts1, end_ts: @ts1, user_id: @user_id
|
||||
v: 42
|
||||
}, {
|
||||
op: { p: 6, i: "bar" }
|
||||
meta: start_ts: @ts1, end_ts: @ts1, user_id: @user_id
|
||||
v: 43
|
||||
}]
|
||||
|
||||
describe "noop - delete", ->
|
||||
it "should leave them untouched", ->
|
||||
expect(@UpdateCompressor.compressUpdates [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: ts: @ts1, user_id: @user_id
|
||||
v: 42
|
||||
}, {
|
||||
op: { p: 6, d: "bar" }
|
||||
meta: ts: @ts1, user_id: @user_id
|
||||
v: 43
|
||||
}])
|
||||
.to.deep.equal [{
|
||||
op: @UpdateCompressor.NOOP
|
||||
meta: start_ts: @ts1, end_ts: @ts1, user_id: @user_id
|
||||
v: 42
|
||||
}, {
|
||||
op: { p: 6, d: "bar" }
|
||||
meta: start_ts: @ts1, end_ts: @ts1, user_id: @user_id
|
||||
v: 43
|
||||
}]
|
||||
|
|
Loading…
Reference in a new issue