sharedb 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/submit-request.js +25 -2
- package/package.json +1 -1
- package/test/client/query.js +38 -0
- package/test/client/submit.js +229 -155
- package/test/db.js +72 -72
package/lib/submit-request.js
CHANGED
|
@@ -109,8 +109,8 @@ SubmitRequest.prototype.submit = function(callback) {
|
|
|
109
109
|
// case, we should return a non-fatal 'Op already submitted' error. We
|
|
110
110
|
// must get the past ops and check their src and seq values to
|
|
111
111
|
// differentiate.
|
|
112
|
-
|
|
113
|
-
if (
|
|
112
|
+
request._fetchCreateOpVersion(function(error, version) {
|
|
113
|
+
if (error) return callback(error);
|
|
114
114
|
if (version == null) {
|
|
115
115
|
callback(request.alreadyCreatedError());
|
|
116
116
|
} else {
|
|
@@ -194,6 +194,15 @@ SubmitRequest.prototype.commit = function(callback) {
|
|
|
194
194
|
backend.trigger(backend.MIDDLEWARE_ACTIONS.commit, this.agent, this, function(err) {
|
|
195
195
|
if (err) return callback(err);
|
|
196
196
|
if (request._fixupOps.length) request.op.m.fixup = request._fixupOps;
|
|
197
|
+
if (request.op.create) {
|
|
198
|
+
// When we create the snapshot, we store a pointer to the op that created
|
|
199
|
+
// it. This allows us to return OP_ALREADY_SUBMITTED errors when appropriate.
|
|
200
|
+
request.snapshot.m._create = {
|
|
201
|
+
src: request.op.src,
|
|
202
|
+
seq: request.op.seq,
|
|
203
|
+
v: request.op.v
|
|
204
|
+
};
|
|
205
|
+
}
|
|
197
206
|
|
|
198
207
|
// Try committing the operation and snapshot to the database atomically
|
|
199
208
|
backend.db.commit(
|
|
@@ -290,6 +299,20 @@ SubmitRequest.prototype._shouldSaveMilestoneSnapshot = function(snapshot) {
|
|
|
290
299
|
return this.saveMilestoneSnapshot;
|
|
291
300
|
};
|
|
292
301
|
|
|
302
|
+
SubmitRequest.prototype._fetchCreateOpVersion = function(callback) {
|
|
303
|
+
var create = this.snapshot.m._create;
|
|
304
|
+
if (create) {
|
|
305
|
+
var version = (create.src === this.op.src && create.seq === this.op.seq) ? create.v : null;
|
|
306
|
+
return callback(null, version);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// We can only reach here if the snapshot is missing the create metadata.
|
|
310
|
+
// This can happen if a client tries to re-create or resubmit a create op to
|
|
311
|
+
// a "legacy" snapshot that existed before we started adding the meta (should
|
|
312
|
+
// be uncommon) or when using a driver that doesn't support metadata (eg Postgres).
|
|
313
|
+
this.backend.db.getCommittedOpVersion(this.collection, this.id, this.snapshot, this.op, null, callback);
|
|
314
|
+
};
|
|
315
|
+
|
|
293
316
|
// Non-fatal client errors:
|
|
294
317
|
SubmitRequest.prototype.alreadySubmittedError = function() {
|
|
295
318
|
return new ShareDBError(ERROR_CODE.ERR_OP_ALREADY_SUBMITTED, 'Op already submitted');
|
package/package.json
CHANGED
package/test/client/query.js
CHANGED
|
@@ -172,5 +172,43 @@ module.exports = function(options) {
|
|
|
172
172
|
});
|
|
173
173
|
});
|
|
174
174
|
});
|
|
175
|
+
|
|
176
|
+
it('snapshot fetch from query does not advance version of doc with pending ops', function(done) {
|
|
177
|
+
var backend = this.backend;
|
|
178
|
+
backend.connect(null, null, function(connection1) {
|
|
179
|
+
backend.connect(null, null, function(connection2) {
|
|
180
|
+
var doc = connection1.get('dogs', 'fido');
|
|
181
|
+
var doc2 = connection2.get('dogs', 'fido');
|
|
182
|
+
doc.create({name: 'kido'}, function(err) {
|
|
183
|
+
if (err) return done(err);
|
|
184
|
+
doc2.fetch(function(err) {
|
|
185
|
+
if (err) return done(err);
|
|
186
|
+
doc2.submitOp({p: ['name', 0], si: 'f'}, function(err) {
|
|
187
|
+
if (err) return done(err);
|
|
188
|
+
expect(doc2.data).eql({name: 'fkido'});
|
|
189
|
+
doc.connection.createFetchQuery('dogs', {}, null, function(err) {
|
|
190
|
+
if (err) return done(err);
|
|
191
|
+
doc.resume();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
process.nextTick(function() {
|
|
197
|
+
doc.pause();
|
|
198
|
+
doc.submitOp({p: ['name', 0], sd: 'k'}, function(err) {
|
|
199
|
+
if (err) return done(err);
|
|
200
|
+
doc.pause();
|
|
201
|
+
doc2.fetch(function(err) {
|
|
202
|
+
if (err) return done(err);
|
|
203
|
+
expect(doc2.version).equal(3);
|
|
204
|
+
expect(doc2.data).eql({name: 'fido'});
|
|
205
|
+
done();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
doc.del();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
175
213
|
});
|
|
176
214
|
};
|
package/test/client/submit.js
CHANGED
|
@@ -13,8 +13,15 @@ types.register(richText.type);
|
|
|
13
13
|
|
|
14
14
|
module.exports = function() {
|
|
15
15
|
describe('client submit', function() {
|
|
16
|
+
var id;
|
|
17
|
+
var idCount = 0;
|
|
18
|
+
|
|
19
|
+
beforeEach(function() {
|
|
20
|
+
id = 'dog-' + idCount++;
|
|
21
|
+
});
|
|
22
|
+
|
|
16
23
|
it('can fetch an uncreated doc', function(done) {
|
|
17
|
-
var doc = this.backend.connect().get('dogs',
|
|
24
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
18
25
|
expect(doc.data).equal(undefined);
|
|
19
26
|
expect(doc.version).equal(null);
|
|
20
27
|
doc.fetch(function(err) {
|
|
@@ -26,7 +33,7 @@ module.exports = function() {
|
|
|
26
33
|
});
|
|
27
34
|
|
|
28
35
|
it('can fetch then create a new doc', function(done) {
|
|
29
|
-
var doc = this.backend.connect().get('dogs',
|
|
36
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
30
37
|
doc.fetch(function(err) {
|
|
31
38
|
if (err) return done(err);
|
|
32
39
|
doc.create({age: 3}, function(err) {
|
|
@@ -39,7 +46,7 @@ module.exports = function() {
|
|
|
39
46
|
});
|
|
40
47
|
|
|
41
48
|
it('can create a new doc without fetching', function(done) {
|
|
42
|
-
var doc = this.backend.connect().get('dogs',
|
|
49
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
43
50
|
doc.create({age: 3}, function(err) {
|
|
44
51
|
if (err) return done(err);
|
|
45
52
|
expect(doc.data).eql({age: 3});
|
|
@@ -54,7 +61,7 @@ module.exports = function() {
|
|
|
54
61
|
foo: 'bar'
|
|
55
62
|
};
|
|
56
63
|
var getSnapshotSpy = sinon.spy(this.backend.db, 'getSnapshot');
|
|
57
|
-
connection.get('dogs',
|
|
64
|
+
connection.get('dogs', id).create({age: 3}, function(err) {
|
|
58
65
|
if (err) return done(err);
|
|
59
66
|
expect(getSnapshotSpy.firstCall.args[3]).to.haveOwnProperty('agentCustom').that.deep.equals({foo: 'bar'});
|
|
60
67
|
done();
|
|
@@ -62,7 +69,7 @@ module.exports = function() {
|
|
|
62
69
|
});
|
|
63
70
|
|
|
64
71
|
it('can create then delete then create a doc', function(done) {
|
|
65
|
-
var doc = this.backend.connect().get('dogs',
|
|
72
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
66
73
|
doc.create({age: 3}, function(err) {
|
|
67
74
|
if (err) return done(err);
|
|
68
75
|
expect(doc.data).eql({age: 3});
|
|
@@ -84,7 +91,7 @@ module.exports = function() {
|
|
|
84
91
|
});
|
|
85
92
|
|
|
86
93
|
it('can create then submit an op', function(done) {
|
|
87
|
-
var doc = this.backend.connect().get('dogs',
|
|
94
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
88
95
|
doc.create({age: 3}, function(err) {
|
|
89
96
|
if (err) return done(err);
|
|
90
97
|
doc.submitOp({p: ['age'], na: 2}, function(err) {
|
|
@@ -97,7 +104,7 @@ module.exports = function() {
|
|
|
97
104
|
});
|
|
98
105
|
|
|
99
106
|
it('can create then submit an op sync', function(done) {
|
|
100
|
-
var doc = this.backend.connect().get('dogs',
|
|
107
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
101
108
|
doc.create({age: 3});
|
|
102
109
|
expect(doc.data).eql({age: 3});
|
|
103
110
|
expect(doc.version).eql(null);
|
|
@@ -108,7 +115,7 @@ module.exports = function() {
|
|
|
108
115
|
});
|
|
109
116
|
|
|
110
117
|
it('submitting an op from a future version fails', function(done) {
|
|
111
|
-
var doc = this.backend.connect().get('dogs',
|
|
118
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
112
119
|
doc.create({age: 3}, function(err) {
|
|
113
120
|
if (err) return done(err);
|
|
114
121
|
doc.version++;
|
|
@@ -120,7 +127,7 @@ module.exports = function() {
|
|
|
120
127
|
});
|
|
121
128
|
|
|
122
129
|
it('cannot submit op on an uncreated doc', function(done) {
|
|
123
|
-
var doc = this.backend.connect().get('dogs',
|
|
130
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
124
131
|
doc.submitOp({p: ['age'], na: 2}, function(err) {
|
|
125
132
|
expect(err).instanceOf(Error);
|
|
126
133
|
done();
|
|
@@ -128,7 +135,7 @@ module.exports = function() {
|
|
|
128
135
|
});
|
|
129
136
|
|
|
130
137
|
it('cannot delete an uncreated doc', function(done) {
|
|
131
|
-
var doc = this.backend.connect().get('dogs',
|
|
138
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
132
139
|
doc.del(function(err) {
|
|
133
140
|
expect(err).instanceOf(Error);
|
|
134
141
|
done();
|
|
@@ -136,7 +143,7 @@ module.exports = function() {
|
|
|
136
143
|
});
|
|
137
144
|
|
|
138
145
|
it('ops submitted sync get composed', function(done) {
|
|
139
|
-
var doc = this.backend.connect().get('dogs',
|
|
146
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
140
147
|
doc.create({age: 3});
|
|
141
148
|
doc.submitOp({p: ['age'], na: 2});
|
|
142
149
|
doc.submitOp({p: ['age'], na: 2}, function(err) {
|
|
@@ -163,7 +170,7 @@ module.exports = function() {
|
|
|
163
170
|
});
|
|
164
171
|
|
|
165
172
|
it('does not compose ops when doc.preventCompose is true', function(done) {
|
|
166
|
-
var doc = this.backend.connect().get('dogs',
|
|
173
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
167
174
|
doc.preventCompose = true;
|
|
168
175
|
doc.create({age: 3});
|
|
169
176
|
doc.submitOp({p: ['age'], na: 2});
|
|
@@ -184,7 +191,7 @@ module.exports = function() {
|
|
|
184
191
|
});
|
|
185
192
|
|
|
186
193
|
it('resumes composing after doc.preventCompose is set back to false', function(done) {
|
|
187
|
-
var doc = this.backend.connect().get('dogs',
|
|
194
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
188
195
|
doc.preventCompose = true;
|
|
189
196
|
doc.create({age: 3});
|
|
190
197
|
doc.submitOp({p: ['age'], na: 2});
|
|
@@ -206,49 +213,154 @@ module.exports = function() {
|
|
|
206
213
|
});
|
|
207
214
|
});
|
|
208
215
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
doc.fetch(function(err) {
|
|
214
|
-
if (err) return done(err);
|
|
215
|
-
expect(doc.data).eql({age: 3});
|
|
216
|
-
expect(doc.version).eql(1);
|
|
217
|
-
done();
|
|
218
|
-
});
|
|
216
|
+
|
|
217
|
+
describe('create', function() {
|
|
218
|
+
describe('metadata enabled', function() {
|
|
219
|
+
runCreateTests();
|
|
219
220
|
});
|
|
220
|
-
});
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
222
|
+
describe('no snapshot metadata available', function() {
|
|
223
|
+
beforeEach(function() {
|
|
224
|
+
var getSnapshot = this.backend.db.getSnapshot;
|
|
225
|
+
sinon.stub(this.backend.db, 'getSnapshot')
|
|
226
|
+
.callsFake(function() {
|
|
227
|
+
var args = Array.from(arguments);
|
|
228
|
+
var callback = args.pop();
|
|
229
|
+
args.push(function(error, snapshot) {
|
|
230
|
+
if (snapshot) delete snapshot.m;
|
|
231
|
+
callback(error, snapshot);
|
|
232
|
+
});
|
|
233
|
+
getSnapshot.apply(this, args);
|
|
234
|
+
});
|
|
231
235
|
});
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
236
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
237
|
+
afterEach(function() {
|
|
238
|
+
sinon.restore();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
runCreateTests();
|
|
242
|
+
|
|
243
|
+
it('returns errors if the database cannot get committed op version', function(done) {
|
|
244
|
+
sinon.stub(this.backend.db, 'getCommittedOpVersion')
|
|
245
|
+
.callsFake(function() {
|
|
246
|
+
var args = Array.from(arguments);
|
|
247
|
+
var callback = args.pop();
|
|
248
|
+
callback(new Error('uh-oh'));
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
var doc1 = this.backend.connect().get('dogs', 'fido');
|
|
252
|
+
var doc2 = this.backend.connect().get('dogs', 'fido');
|
|
253
|
+
async.series([
|
|
254
|
+
doc1.create.bind(doc1, {age: 3}),
|
|
255
|
+
function(next) {
|
|
256
|
+
doc2.create({name: 'Fido'}, function(error) {
|
|
257
|
+
expect(error.message).to.equal('uh-oh');
|
|
258
|
+
next();
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
], done);
|
|
245
262
|
});
|
|
246
263
|
});
|
|
264
|
+
|
|
265
|
+
function runCreateTests() {
|
|
266
|
+
it('can create a new doc then fetch', function(done) {
|
|
267
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
268
|
+
doc.create({age: 3}, function(err) {
|
|
269
|
+
if (err) return done(err);
|
|
270
|
+
doc.fetch(function(err) {
|
|
271
|
+
if (err) return done(err);
|
|
272
|
+
expect(doc.data).eql({age: 3});
|
|
273
|
+
expect(doc.version).eql(1);
|
|
274
|
+
done();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('calling create on the same doc twice fails', function(done) {
|
|
280
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
281
|
+
doc.create({age: 3}, function(err) {
|
|
282
|
+
if (err) return done(err);
|
|
283
|
+
doc.create({age: 4}, function(err) {
|
|
284
|
+
expect(err).instanceOf(Error);
|
|
285
|
+
expect(doc.version).equal(1);
|
|
286
|
+
expect(doc.data).eql({age: 3});
|
|
287
|
+
done();
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('trying to create an already created doc without fetching fails and fetches', function(done) {
|
|
293
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
294
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
295
|
+
doc.create({age: 3}, function(err) {
|
|
296
|
+
if (err) return done(err);
|
|
297
|
+
doc2.create({age: 4}, function(err) {
|
|
298
|
+
expect(err).instanceOf(Error);
|
|
299
|
+
expect(doc2.version).equal(1);
|
|
300
|
+
expect(doc2.data).eql({age: 3});
|
|
301
|
+
done();
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('does not fail when resubmitting a create op', function(done) {
|
|
307
|
+
var backend = this.backend;
|
|
308
|
+
var connection = backend.connect();
|
|
309
|
+
var submitted = false;
|
|
310
|
+
backend.use('submit', function(request, next) {
|
|
311
|
+
if (!submitted) {
|
|
312
|
+
submitted = true;
|
|
313
|
+
connection.close();
|
|
314
|
+
backend.connect(connection);
|
|
315
|
+
}
|
|
316
|
+
next();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
var count = 0;
|
|
320
|
+
backend.use('reply', function(message, next) {
|
|
321
|
+
next();
|
|
322
|
+
if (message.reply.a === 'op') count++;
|
|
323
|
+
if (count === 2) done();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
var doc = connection.get('dogs', id);
|
|
327
|
+
doc.create({age: 10}, errorHandler(done));
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('does not fail when resubmitting a create op on a doc that was deleted', function(done) {
|
|
331
|
+
var backend = this.backend;
|
|
332
|
+
var connection1 = backend.connect();
|
|
333
|
+
var connection2 = backend.connect();
|
|
334
|
+
var doc1 = connection1.get('dogs', id);
|
|
335
|
+
var doc2 = connection2.get('dogs', id);
|
|
336
|
+
|
|
337
|
+
async.series([
|
|
338
|
+
doc1.create.bind(doc1, {age: 3}),
|
|
339
|
+
doc1.del.bind(doc1),
|
|
340
|
+
function(next) {
|
|
341
|
+
var submitted = false;
|
|
342
|
+
backend.use('submit', function(request, next) {
|
|
343
|
+
if (!submitted) {
|
|
344
|
+
submitted = true;
|
|
345
|
+
connection2.close();
|
|
346
|
+
backend.connect(connection2);
|
|
347
|
+
}
|
|
348
|
+
next();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
doc2.create({name: 'Fido'}, function(error) {
|
|
352
|
+
expect(doc2.version).to.equal(3);
|
|
353
|
+
next(error);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
], done);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
247
359
|
});
|
|
248
360
|
|
|
249
361
|
it('server fetches and transforms by already committed op', function(done) {
|
|
250
|
-
var doc = this.backend.connect().get('dogs',
|
|
251
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
362
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
363
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
252
364
|
doc.create({age: 3}, function(err) {
|
|
253
365
|
if (err) return done(err);
|
|
254
366
|
doc2.fetch(function(err) {
|
|
@@ -270,8 +382,8 @@ module.exports = function() {
|
|
|
270
382
|
this.backend.db.getOpsToSnapshot = function(collection, id, from, snapshot, options, callback) {
|
|
271
383
|
callback(null, []);
|
|
272
384
|
};
|
|
273
|
-
var doc = this.backend.connect().get('dogs',
|
|
274
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
385
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
386
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
275
387
|
doc.create({age: 3}, function(err) {
|
|
276
388
|
if (err) return done(err);
|
|
277
389
|
doc2.fetch(function(err) {
|
|
@@ -295,8 +407,8 @@ module.exports = function() {
|
|
|
295
407
|
callback(null, ops);
|
|
296
408
|
});
|
|
297
409
|
};
|
|
298
|
-
var doc = this.backend.connect().get('dogs',
|
|
299
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
410
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
411
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
300
412
|
doc.create({age: 3}, function(err) {
|
|
301
413
|
if (err) return done(err);
|
|
302
414
|
doc2.fetch(function(err) {
|
|
@@ -326,7 +438,7 @@ module.exports = function() {
|
|
|
326
438
|
|
|
327
439
|
it('resends create when disconnected before ack', function(done) {
|
|
328
440
|
var backend = this.backend;
|
|
329
|
-
var doc = backend.connect().get('dogs',
|
|
441
|
+
var doc = backend.connect().get('dogs', id);
|
|
330
442
|
doc.create({age: 3}, function(err) {
|
|
331
443
|
if (err) return done(err);
|
|
332
444
|
expect(doc.version).equal(1);
|
|
@@ -338,13 +450,13 @@ module.exports = function() {
|
|
|
338
450
|
|
|
339
451
|
it('resent create on top of deleted doc gets proper starting version', function(done) {
|
|
340
452
|
var backend = this.backend;
|
|
341
|
-
var doc = backend.connect().get('dogs',
|
|
453
|
+
var doc = backend.connect().get('dogs', id);
|
|
342
454
|
doc.create({age: 4}, function(err) {
|
|
343
455
|
if (err) return done(err);
|
|
344
456
|
doc.del(function(err) {
|
|
345
457
|
if (err) return done(err);
|
|
346
458
|
|
|
347
|
-
var doc2 = backend.connect().get('dogs',
|
|
459
|
+
var doc2 = backend.connect().get('dogs', id);
|
|
348
460
|
doc2.create({age: 3}, function(err) {
|
|
349
461
|
if (err) return done(err);
|
|
350
462
|
expect(doc2.version).equal(3);
|
|
@@ -358,7 +470,7 @@ module.exports = function() {
|
|
|
358
470
|
|
|
359
471
|
it('resends delete when disconnected before ack', function(done) {
|
|
360
472
|
var backend = this.backend;
|
|
361
|
-
var doc = backend.connect().get('dogs',
|
|
473
|
+
var doc = backend.connect().get('dogs', id);
|
|
362
474
|
doc.create({age: 3}, function(err) {
|
|
363
475
|
if (err) return done(err);
|
|
364
476
|
doc.del(function(err) {
|
|
@@ -373,7 +485,7 @@ module.exports = function() {
|
|
|
373
485
|
|
|
374
486
|
it('op submitted during inflight create does not compose and gets flushed', function(done) {
|
|
375
487
|
this.backend.connect(null, null, function(connection) {
|
|
376
|
-
var doc = connection.get('dogs',
|
|
488
|
+
var doc = connection.get('dogs', id);
|
|
377
489
|
doc.create({age: 3});
|
|
378
490
|
// Submit an op after message is sent but before server has a chance to reply
|
|
379
491
|
process.nextTick(function() {
|
|
@@ -388,8 +500,8 @@ module.exports = function() {
|
|
|
388
500
|
});
|
|
389
501
|
|
|
390
502
|
it('can commit then fetch in a new connection to get the same data', function(done) {
|
|
391
|
-
var doc = this.backend.connect().get('dogs',
|
|
392
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
503
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
504
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
393
505
|
doc.create({age: 3}, function(err) {
|
|
394
506
|
if (err) return done(err);
|
|
395
507
|
doc2.fetch(function(err) {
|
|
@@ -405,8 +517,8 @@ module.exports = function() {
|
|
|
405
517
|
});
|
|
406
518
|
|
|
407
519
|
it('an op submitted concurrently is transformed by the first', function(done) {
|
|
408
|
-
var doc = this.backend.connect().get('dogs',
|
|
409
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
520
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
521
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
410
522
|
doc.create({age: 3}, function(err) {
|
|
411
523
|
if (err) return done(err);
|
|
412
524
|
doc2.fetch(function(err) {
|
|
@@ -441,8 +553,8 @@ module.exports = function() {
|
|
|
441
553
|
});
|
|
442
554
|
|
|
443
555
|
it('second of two concurrent creates is rejected', function(done) {
|
|
444
|
-
var doc = this.backend.connect().get('dogs',
|
|
445
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
556
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
557
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
446
558
|
var count = 0;
|
|
447
559
|
doc.create({age: 3}, function(err) {
|
|
448
560
|
count++;
|
|
@@ -473,8 +585,8 @@ module.exports = function() {
|
|
|
473
585
|
});
|
|
474
586
|
|
|
475
587
|
it('concurrent delete operations transform', function(done) {
|
|
476
|
-
var doc = this.backend.connect().get('dogs',
|
|
477
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
588
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
589
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
478
590
|
doc.create({age: 3}, function(err) {
|
|
479
591
|
if (err) return done(err);
|
|
480
592
|
doc2.fetch(function(err) {
|
|
@@ -510,8 +622,8 @@ module.exports = function() {
|
|
|
510
622
|
|
|
511
623
|
it('submits retry below the backend.maxSubmitRetries threshold', function(done) {
|
|
512
624
|
this.backend.maxSubmitRetries = 10;
|
|
513
|
-
var doc = this.backend.connect().get('dogs',
|
|
514
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
625
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
626
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
515
627
|
doc.create({age: 3}, function(err) {
|
|
516
628
|
if (err) return done(err);
|
|
517
629
|
doc2.fetch(function(err) {
|
|
@@ -531,8 +643,8 @@ module.exports = function() {
|
|
|
531
643
|
it('submits fail above the backend.maxSubmitRetries threshold', function(done) {
|
|
532
644
|
var backend = this.backend;
|
|
533
645
|
this.backend.maxSubmitRetries = 0;
|
|
534
|
-
var doc = this.backend.connect().get('dogs',
|
|
535
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
646
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
647
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
536
648
|
doc.create({age: 3}, function(err) {
|
|
537
649
|
if (err) return done(err);
|
|
538
650
|
doc2.fetch(function(err) {
|
|
@@ -572,8 +684,8 @@ module.exports = function() {
|
|
|
572
684
|
});
|
|
573
685
|
|
|
574
686
|
it('pending delete transforms incoming ops', function(done) {
|
|
575
|
-
var doc = this.backend.connect().get('dogs',
|
|
576
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
687
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
688
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
577
689
|
doc.create({age: 3}, function(err) {
|
|
578
690
|
if (err) return done(err);
|
|
579
691
|
doc2.fetch(function(err) {
|
|
@@ -599,8 +711,8 @@ module.exports = function() {
|
|
|
599
711
|
});
|
|
600
712
|
|
|
601
713
|
it('pending delete transforms incoming delete', function(done) {
|
|
602
|
-
var doc = this.backend.connect().get('dogs',
|
|
603
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
714
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
715
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
604
716
|
doc.create({age: 3}, function(err) {
|
|
605
717
|
if (err) return done(err);
|
|
606
718
|
doc2.fetch(function(err) {
|
|
@@ -626,8 +738,8 @@ module.exports = function() {
|
|
|
626
738
|
});
|
|
627
739
|
|
|
628
740
|
it('submitting op after delete returns error', function(done) {
|
|
629
|
-
var doc = this.backend.connect().get('dogs',
|
|
630
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
741
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
742
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
631
743
|
doc.create({age: 3}, function(err) {
|
|
632
744
|
if (err) return done(err);
|
|
633
745
|
doc2.fetch(function(err) {
|
|
@@ -646,8 +758,8 @@ module.exports = function() {
|
|
|
646
758
|
});
|
|
647
759
|
|
|
648
760
|
it('transforming pending op by server delete returns error', function(done) {
|
|
649
|
-
var doc = this.backend.connect().get('dogs',
|
|
650
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
761
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
762
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
651
763
|
doc.create({age: 3}, function(err) {
|
|
652
764
|
if (err) return done(err);
|
|
653
765
|
doc2.fetch(function(err) {
|
|
@@ -668,8 +780,8 @@ module.exports = function() {
|
|
|
668
780
|
});
|
|
669
781
|
|
|
670
782
|
it('transforming pending op by server create returns error', function(done) {
|
|
671
|
-
var doc = this.backend.connect().get('dogs',
|
|
672
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
783
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
784
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
673
785
|
doc.create({age: 3}, function(err) {
|
|
674
786
|
if (err) return done(err);
|
|
675
787
|
doc.del(function(err) {
|
|
@@ -693,8 +805,8 @@ module.exports = function() {
|
|
|
693
805
|
});
|
|
694
806
|
|
|
695
807
|
it('second client can create following delete', function(done) {
|
|
696
|
-
var doc = this.backend.connect().get('dogs',
|
|
697
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
808
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
809
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
698
810
|
doc.create({age: 3}, function(err) {
|
|
699
811
|
if (err) return done(err);
|
|
700
812
|
doc.del(function(err) {
|
|
@@ -710,28 +822,28 @@ module.exports = function() {
|
|
|
710
822
|
});
|
|
711
823
|
|
|
712
824
|
it('doc.pause() prevents ops from being sent', function(done) {
|
|
713
|
-
var doc = this.backend.connect().get('dogs',
|
|
825
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
714
826
|
doc.pause();
|
|
715
827
|
doc.create({age: 3}, done);
|
|
716
828
|
done();
|
|
717
829
|
});
|
|
718
830
|
|
|
719
831
|
it('can call doc.resume() without pausing', function(done) {
|
|
720
|
-
var doc = this.backend.connect().get('dogs',
|
|
832
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
721
833
|
doc.resume();
|
|
722
834
|
doc.create({age: 3}, done);
|
|
723
835
|
});
|
|
724
836
|
|
|
725
837
|
it('doc.resume() resumes sending ops after pause', function(done) {
|
|
726
|
-
var doc = this.backend.connect().get('dogs',
|
|
838
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
727
839
|
doc.pause();
|
|
728
840
|
doc.create({age: 3}, done);
|
|
729
841
|
doc.resume();
|
|
730
842
|
});
|
|
731
843
|
|
|
732
844
|
it('pending ops are transformed by ops from other clients', function(done) {
|
|
733
|
-
var doc = this.backend.connect().get('dogs',
|
|
734
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
845
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
846
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
735
847
|
doc.create({age: 3}, function(err) {
|
|
736
848
|
if (err) return done(err);
|
|
737
849
|
doc2.fetch(function(err) {
|
|
@@ -786,7 +898,7 @@ module.exports = function() {
|
|
|
786
898
|
});
|
|
787
899
|
|
|
788
900
|
it('snapshot fetch does not revert the version of deleted doc without pending ops', function(done) {
|
|
789
|
-
var doc = this.backend.connect().get('dogs',
|
|
901
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
790
902
|
this.backend.use('readSnapshots', function(request, next) {
|
|
791
903
|
doc.create({age: 3});
|
|
792
904
|
doc.del(next);
|
|
@@ -799,7 +911,7 @@ module.exports = function() {
|
|
|
799
911
|
});
|
|
800
912
|
|
|
801
913
|
it('snapshot fetch does not revert the version of deleted doc with pending ops', function(done) {
|
|
802
|
-
var doc = this.backend.connect().get('dogs',
|
|
914
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
803
915
|
this.backend.use('readSnapshots', function(request, next) {
|
|
804
916
|
doc.create({age: 3}, function(err) {
|
|
805
917
|
if (err) return done(err);
|
|
@@ -817,49 +929,11 @@ module.exports = function() {
|
|
|
817
929
|
});
|
|
818
930
|
});
|
|
819
931
|
|
|
820
|
-
it('snapshot fetch from query does not advance version of doc with pending ops', function(done) {
|
|
821
|
-
var backend = this.backend;
|
|
822
|
-
backend.connect(null, null, function(connection1) {
|
|
823
|
-
backend.connect(null, null, function(connection2) {
|
|
824
|
-
var doc = connection1.get('dogs', 'fido');
|
|
825
|
-
var doc2 = connection2.get('dogs', 'fido');
|
|
826
|
-
doc.create({name: 'kido'}, function(err) {
|
|
827
|
-
if (err) return done(err);
|
|
828
|
-
doc2.fetch(function(err) {
|
|
829
|
-
if (err) return done(err);
|
|
830
|
-
doc2.submitOp({p: ['name', 0], si: 'f'}, function(err) {
|
|
831
|
-
if (err) return done(err);
|
|
832
|
-
expect(doc2.data).eql({name: 'fkido'});
|
|
833
|
-
doc.connection.createFetchQuery('dogs', {}, null, function(err) {
|
|
834
|
-
if (err) return done(err);
|
|
835
|
-
doc.resume();
|
|
836
|
-
});
|
|
837
|
-
});
|
|
838
|
-
});
|
|
839
|
-
});
|
|
840
|
-
process.nextTick(function() {
|
|
841
|
-
doc.pause();
|
|
842
|
-
doc.submitOp({p: ['name', 0], sd: 'k'}, function(err) {
|
|
843
|
-
if (err) return done(err);
|
|
844
|
-
doc.pause();
|
|
845
|
-
doc2.fetch(function(err) {
|
|
846
|
-
if (err) return done(err);
|
|
847
|
-
expect(doc2.version).equal(3);
|
|
848
|
-
expect(doc2.data).eql({name: 'fido'});
|
|
849
|
-
done();
|
|
850
|
-
});
|
|
851
|
-
});
|
|
852
|
-
doc.del();
|
|
853
|
-
});
|
|
854
|
-
});
|
|
855
|
-
});
|
|
856
|
-
});
|
|
857
|
-
|
|
858
932
|
it('passing an error in submit middleware rejects a create and calls back with the erorr', function(done) {
|
|
859
933
|
this.backend.use('submit', function(request, next) {
|
|
860
934
|
next({message: 'Custom error'});
|
|
861
935
|
});
|
|
862
|
-
var doc = this.backend.connect().get('dogs',
|
|
936
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
863
937
|
doc.create({age: 3}, function(err) {
|
|
864
938
|
expect(err.message).equal('Custom error');
|
|
865
939
|
expect(doc.version).equal(0);
|
|
@@ -874,7 +948,7 @@ module.exports = function() {
|
|
|
874
948
|
this.backend.use('submit', function(request, next) {
|
|
875
949
|
next({message: 'Custom error'});
|
|
876
950
|
});
|
|
877
|
-
var doc = this.backend.connect().get('dogs',
|
|
951
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
878
952
|
doc.create({age: 3});
|
|
879
953
|
expect(doc.version).equal(null);
|
|
880
954
|
expect(doc.data).eql({age: 3});
|
|
@@ -893,7 +967,7 @@ module.exports = function() {
|
|
|
893
967
|
if (submitCount === 1) return next({message: 'Custom error'});
|
|
894
968
|
next();
|
|
895
969
|
});
|
|
896
|
-
var doc = this.backend.connect().get('dogs',
|
|
970
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
897
971
|
async.parallel([
|
|
898
972
|
function(cb) {
|
|
899
973
|
doc.create({age: 3}, function(err) {
|
|
@@ -930,7 +1004,7 @@ module.exports = function() {
|
|
|
930
1004
|
});
|
|
931
1005
|
|
|
932
1006
|
var connection = this.backend.connect();
|
|
933
|
-
var doc = connection.get('dogs',
|
|
1007
|
+
var doc = connection.get('dogs', id);
|
|
934
1008
|
doc.preventCompose = true;
|
|
935
1009
|
|
|
936
1010
|
doc.create({age: 3}, function(error) {
|
|
@@ -946,7 +1020,7 @@ module.exports = function() {
|
|
|
946
1020
|
this.backend.use('submit', function(request, next) {
|
|
947
1021
|
next(request.rejectedError());
|
|
948
1022
|
});
|
|
949
|
-
var doc = this.backend.connect().get('dogs',
|
|
1023
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
950
1024
|
doc.create({age: 3}, function(err) {
|
|
951
1025
|
if (err) return done(err);
|
|
952
1026
|
expect(doc.version).equal(0);
|
|
@@ -961,7 +1035,7 @@ module.exports = function() {
|
|
|
961
1035
|
this.backend.use('submit', function(request, next) {
|
|
962
1036
|
next(request.rejectedError());
|
|
963
1037
|
});
|
|
964
|
-
var doc = this.backend.connect().get('dogs',
|
|
1038
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
965
1039
|
doc.create({age: 3});
|
|
966
1040
|
expect(doc.version).equal(null);
|
|
967
1041
|
expect(doc.data).eql({age: 3});
|
|
@@ -982,7 +1056,7 @@ module.exports = function() {
|
|
|
982
1056
|
});
|
|
983
1057
|
|
|
984
1058
|
var connection = this.backend.connect();
|
|
985
|
-
var doc = connection.get('dogs',
|
|
1059
|
+
var doc = connection.get('dogs', id);
|
|
986
1060
|
doc.preventCompose = true;
|
|
987
1061
|
|
|
988
1062
|
doc.create({age: 3});
|
|
@@ -1000,7 +1074,7 @@ module.exports = function() {
|
|
|
1000
1074
|
if ('op' in request.op) return next({message: 'Custom error'});
|
|
1001
1075
|
next();
|
|
1002
1076
|
});
|
|
1003
|
-
var doc = this.backend.connect().get('dogs',
|
|
1077
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1004
1078
|
doc.create({age: 3}, function(err) {
|
|
1005
1079
|
if (err) return done(err);
|
|
1006
1080
|
doc.submitOp({p: ['age'], na: 1}, function(err) {
|
|
@@ -1019,7 +1093,7 @@ module.exports = function() {
|
|
|
1019
1093
|
if ('op' in request.op) return next({message: 'Custom error'});
|
|
1020
1094
|
next();
|
|
1021
1095
|
});
|
|
1022
|
-
var doc = this.backend.connect().get('dogs',
|
|
1096
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1023
1097
|
doc.create({age: 3}, function(err) {
|
|
1024
1098
|
if (err) return done(err);
|
|
1025
1099
|
doc.submitOp({p: ['age'], na: 1});
|
|
@@ -1041,7 +1115,7 @@ module.exports = function() {
|
|
|
1041
1115
|
if (submitCount === 2) return next({message: 'Custom error'});
|
|
1042
1116
|
next();
|
|
1043
1117
|
});
|
|
1044
|
-
var doc = this.backend.connect().get('dogs',
|
|
1118
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1045
1119
|
doc.create({age: 3}, function(err) {
|
|
1046
1120
|
if (err) return done(err);
|
|
1047
1121
|
async.parallel([
|
|
@@ -1075,7 +1149,7 @@ module.exports = function() {
|
|
|
1075
1149
|
if ('op' in request.op) return next(request.rejectedError());
|
|
1076
1150
|
next();
|
|
1077
1151
|
});
|
|
1078
|
-
var doc = this.backend.connect().get('dogs',
|
|
1152
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1079
1153
|
doc.create({age: 3}, function(err) {
|
|
1080
1154
|
if (err) return done(err);
|
|
1081
1155
|
doc.submitOp({p: ['age'], na: 1}, function(err) {
|
|
@@ -1098,7 +1172,7 @@ module.exports = function() {
|
|
|
1098
1172
|
}
|
|
1099
1173
|
next();
|
|
1100
1174
|
});
|
|
1101
|
-
var doc = this.backend.connect().get('dogs',
|
|
1175
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1102
1176
|
doc.preventCompose = true;
|
|
1103
1177
|
|
|
1104
1178
|
doc.create({age: 3}, function(err) {
|
|
@@ -1128,7 +1202,7 @@ module.exports = function() {
|
|
|
1128
1202
|
}
|
|
1129
1203
|
next();
|
|
1130
1204
|
});
|
|
1131
|
-
var doc = this.backend.connect().get('dogs',
|
|
1205
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1132
1206
|
doc.preventCompose = true;
|
|
1133
1207
|
|
|
1134
1208
|
doc.create({ops: [{insert: 'Scrappy'}]}, 'rich-text', function(err) {
|
|
@@ -1153,7 +1227,7 @@ module.exports = function() {
|
|
|
1153
1227
|
if ('op' in request.op) return next(request.rejectedError());
|
|
1154
1228
|
next();
|
|
1155
1229
|
});
|
|
1156
|
-
var doc = this.backend.connect().get('dogs',
|
|
1230
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1157
1231
|
doc.create({age: 3}, function(err) {
|
|
1158
1232
|
if (err) return done(err);
|
|
1159
1233
|
doc.submitOp({p: ['age'], na: 1});
|
|
@@ -1172,8 +1246,8 @@ module.exports = function() {
|
|
|
1172
1246
|
if (request.op) delete request.op.op;
|
|
1173
1247
|
next();
|
|
1174
1248
|
});
|
|
1175
|
-
var doc = this.backend.connect().get('dogs',
|
|
1176
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
1249
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1250
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
1177
1251
|
doc.create({age: 3}, function(err) {
|
|
1178
1252
|
if (err) return done(err);
|
|
1179
1253
|
doc.submitOp({p: ['age'], na: 1}, function(err) {
|
|
@@ -1193,7 +1267,7 @@ module.exports = function() {
|
|
|
1193
1267
|
});
|
|
1194
1268
|
|
|
1195
1269
|
it('submitting an invalid op message returns error', function(done) {
|
|
1196
|
-
var doc = this.backend.connect().get('dogs',
|
|
1270
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1197
1271
|
doc.create({age: 3}, function(err) {
|
|
1198
1272
|
if (err) return done(err);
|
|
1199
1273
|
doc._submit({}, null, function(err) {
|
|
@@ -1204,7 +1278,7 @@ module.exports = function() {
|
|
|
1204
1278
|
});
|
|
1205
1279
|
|
|
1206
1280
|
it('allows snapshot and op to be a non-object', function(done) {
|
|
1207
|
-
var doc = this.backend.connect().get('dogs',
|
|
1281
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1208
1282
|
doc.create(5, numberType.type.uri, function(err) {
|
|
1209
1283
|
if (err) return done(err);
|
|
1210
1284
|
expect(doc.data).to.equal(5);
|
|
@@ -1218,7 +1292,7 @@ module.exports = function() {
|
|
|
1218
1292
|
|
|
1219
1293
|
describe('type.deserialize', function() {
|
|
1220
1294
|
it('can create a new doc', function(done) {
|
|
1221
|
-
var doc = this.backend.connect().get('dogs',
|
|
1295
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1222
1296
|
doc.create([3], deserializedType.type.uri, function(err) {
|
|
1223
1297
|
if (err) return done(err);
|
|
1224
1298
|
expect(doc.data).instanceOf(deserializedType.Node);
|
|
@@ -1230,10 +1304,10 @@ module.exports = function() {
|
|
|
1230
1304
|
|
|
1231
1305
|
it('is stored serialized in backend', function(done) {
|
|
1232
1306
|
var db = this.backend.db;
|
|
1233
|
-
var doc = this.backend.connect().get('dogs',
|
|
1307
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1234
1308
|
doc.create([3], deserializedType.type.uri, function(err) {
|
|
1235
1309
|
if (err) return done(err);
|
|
1236
|
-
db.getSnapshot('dogs',
|
|
1310
|
+
db.getSnapshot('dogs', id, null, null, function(err, snapshot) {
|
|
1237
1311
|
if (err) return done(err);
|
|
1238
1312
|
expect(snapshot.data).eql([3]);
|
|
1239
1313
|
done();
|
|
@@ -1242,8 +1316,8 @@ module.exports = function() {
|
|
|
1242
1316
|
});
|
|
1243
1317
|
|
|
1244
1318
|
it('deserializes on fetch', function(done) {
|
|
1245
|
-
var doc = this.backend.connect().get('dogs',
|
|
1246
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
1319
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1320
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
1247
1321
|
doc.create([3], deserializedType.type.uri, function(err) {
|
|
1248
1322
|
if (err) return done(err);
|
|
1249
1323
|
doc2.fetch(function(err) {
|
|
@@ -1257,7 +1331,7 @@ module.exports = function() {
|
|
|
1257
1331
|
});
|
|
1258
1332
|
|
|
1259
1333
|
it('can create then submit an op', function(done) {
|
|
1260
|
-
var doc = this.backend.connect().get('dogs',
|
|
1334
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1261
1335
|
doc.create([3], deserializedType.type.uri, function(err) {
|
|
1262
1336
|
if (err) return done(err);
|
|
1263
1337
|
doc.submitOp({insert: 0, value: 2}, function(err) {
|
|
@@ -1271,8 +1345,8 @@ module.exports = function() {
|
|
|
1271
1345
|
});
|
|
1272
1346
|
|
|
1273
1347
|
it('server fetches and transforms by already committed op', function(done) {
|
|
1274
|
-
var doc = this.backend.connect().get('dogs',
|
|
1275
|
-
var doc2 = this.backend.connect().get('dogs',
|
|
1348
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1349
|
+
var doc2 = this.backend.connect().get('dogs', id);
|
|
1276
1350
|
doc.create([3], deserializedType.type.uri, function(err) {
|
|
1277
1351
|
if (err) return done(err);
|
|
1278
1352
|
doc2.fetch(function(err) {
|
|
@@ -1295,7 +1369,7 @@ module.exports = function() {
|
|
|
1295
1369
|
|
|
1296
1370
|
describe('type.createDeserialized', function() {
|
|
1297
1371
|
it('can create a new doc', function(done) {
|
|
1298
|
-
var doc = this.backend.connect().get('dogs',
|
|
1372
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1299
1373
|
doc.create([3], deserializedType.type2.uri, function(err) {
|
|
1300
1374
|
if (err) return done(err);
|
|
1301
1375
|
expect(doc.data).instanceOf(deserializedType.Node);
|
|
@@ -1306,7 +1380,7 @@ module.exports = function() {
|
|
|
1306
1380
|
});
|
|
1307
1381
|
|
|
1308
1382
|
it('can create a new doc from deserialized form', function(done) {
|
|
1309
|
-
var doc = this.backend.connect().get('dogs',
|
|
1383
|
+
var doc = this.backend.connect().get('dogs', id);
|
|
1310
1384
|
doc.create(new deserializedType.Node(3), deserializedType.type2.uri, function(err) {
|
|
1311
1385
|
if (err) return done(err);
|
|
1312
1386
|
expect(doc.data).instanceOf(deserializedType.Node);
|
|
@@ -1323,9 +1397,9 @@ module.exports = function() {
|
|
|
1323
1397
|
|
|
1324
1398
|
beforeEach(function(done) {
|
|
1325
1399
|
var connection = this.backend.connect();
|
|
1326
|
-
doc = connection.get('dogs',
|
|
1400
|
+
doc = connection.get('dogs', id);
|
|
1327
1401
|
var remoteConnection = this.backend.connect();
|
|
1328
|
-
remoteDoc = remoteConnection.get('dogs',
|
|
1402
|
+
remoteDoc = remoteConnection.get('dogs', id);
|
|
1329
1403
|
|
|
1330
1404
|
async.series([
|
|
1331
1405
|
doc.create.bind(doc, {name: 'fido'}),
|
package/test/db.js
CHANGED
|
@@ -61,9 +61,9 @@ module.exports = function(options) {
|
|
|
61
61
|
if (options.getQuery) {
|
|
62
62
|
require('./client/query-subscribe')({getQuery: options.getQuery});
|
|
63
63
|
require('./client/query')({getQuery: options.getQuery});
|
|
64
|
+
require('./client/projections')({getQuery: options.getQuery});
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
require('./client/projections')({getQuery: options.getQuery});
|
|
67
67
|
require('./client/submit')();
|
|
68
68
|
require('./client/submit-json1')();
|
|
69
69
|
require('./client/subscribe')();
|
|
@@ -650,111 +650,111 @@ module.exports = function(options) {
|
|
|
650
650
|
});
|
|
651
651
|
});
|
|
652
652
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
db.query('testcollection', {x: 5}, null, null, function(err, results) {
|
|
653
|
+
if (options.getQuery) {
|
|
654
|
+
describe('query', function() {
|
|
655
|
+
it('query returns data in the collection', function(done) {
|
|
656
|
+
var snapshot = {v: 1, type: 'json0', data: {x: 5, y: 6}, m: null};
|
|
657
|
+
var db = this.db;
|
|
658
|
+
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) {
|
|
660
659
|
if (err) return done(err);
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
660
|
+
db.query('testcollection', {x: 5}, null, null, function(err, results) {
|
|
661
|
+
if (err) return done(err);
|
|
662
|
+
delete results[0].id;
|
|
663
|
+
expect(results).eql([snapshot]);
|
|
664
|
+
done();
|
|
665
|
+
});
|
|
664
666
|
});
|
|
665
667
|
});
|
|
666
|
-
});
|
|
667
668
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
669
|
+
it('query returns nothing when there is no data', function(done) {
|
|
670
|
+
this.db.query('testcollection', {x: 5}, null, null, function(err, results) {
|
|
671
|
+
if (err) return done(err);
|
|
672
|
+
expect(results).eql([]);
|
|
673
|
+
done();
|
|
674
|
+
});
|
|
673
675
|
});
|
|
674
|
-
});
|
|
675
676
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if (err) return done(err);
|
|
680
|
-
db.query('testcollection', {x: 5}, null, null, function(err, results) {
|
|
677
|
+
it('query does not return committed metadata by default', function(done) {
|
|
678
|
+
var db = this.db;
|
|
679
|
+
commitSnapshotWithMetadata(db, function(err) {
|
|
681
680
|
if (err) return done(err);
|
|
682
|
-
|
|
683
|
-
|
|
681
|
+
db.query('testcollection', {x: 5}, null, null, function(err, results) {
|
|
682
|
+
if (err) return done(err);
|
|
683
|
+
expect(results[0].m).equal(null);
|
|
684
|
+
done();
|
|
685
|
+
});
|
|
684
686
|
});
|
|
685
687
|
});
|
|
686
|
-
});
|
|
687
688
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
if (err) return done(err);
|
|
692
|
-
db.query('testcollection', {x: 5}, null, {metadata: true}, function(err, results) {
|
|
689
|
+
it('query returns metadata when option is true', function(done) {
|
|
690
|
+
var db = this.db;
|
|
691
|
+
commitSnapshotWithMetadata(db, function(err) {
|
|
693
692
|
if (err) return done(err);
|
|
694
|
-
|
|
695
|
-
|
|
693
|
+
db.query('testcollection', {x: 5}, null, {metadata: true}, function(err, results) {
|
|
694
|
+
if (err) return done(err);
|
|
695
|
+
expect(results[0].m).eql({test: 3});
|
|
696
|
+
done();
|
|
697
|
+
});
|
|
696
698
|
});
|
|
697
699
|
});
|
|
698
700
|
});
|
|
699
|
-
});
|
|
700
701
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
702
|
+
describe('projections', function() {
|
|
703
|
+
it('query returns only projected fields', function(done) {
|
|
704
|
+
if (!this.db.projectsSnapshot) return done();
|
|
704
705
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
if (err) return done(err);
|
|
709
|
-
db.query('testcollection', {x: 5}, {y: true}, null, function(err, results) {
|
|
706
|
+
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}};
|
|
707
|
+
var db = this.db;
|
|
708
|
+
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) {
|
|
710
709
|
if (err) return done(err);
|
|
711
|
-
|
|
712
|
-
|
|
710
|
+
db.query('testcollection', {x: 5}, {y: true}, null, function(err, results) {
|
|
711
|
+
if (err) return done(err);
|
|
712
|
+
expect(results).eql([{type: 'json0', v: 1, data: {y: 6}, id: 'test'}]);
|
|
713
|
+
done();
|
|
714
|
+
});
|
|
713
715
|
});
|
|
714
716
|
});
|
|
715
|
-
});
|
|
716
717
|
|
|
717
|
-
|
|
718
|
-
|
|
718
|
+
it('query returns no data for matching documents if fields is empty', function(done) {
|
|
719
|
+
if (!this.db.projectsSnapshot) return done();
|
|
719
720
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (err) return done(err);
|
|
724
|
-
db.query('testcollection', {x: 5}, {}, null, function(err, results) {
|
|
721
|
+
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}};
|
|
722
|
+
var db = this.db;
|
|
723
|
+
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) {
|
|
725
724
|
if (err) return done(err);
|
|
726
|
-
|
|
727
|
-
|
|
725
|
+
db.query('testcollection', {x: 5}, {}, null, function(err, results) {
|
|
726
|
+
if (err) return done(err);
|
|
727
|
+
expect(results).eql([{type: 'json0', v: 1, data: {}, id: 'test'}]);
|
|
728
|
+
done();
|
|
729
|
+
});
|
|
728
730
|
});
|
|
729
731
|
});
|
|
730
|
-
});
|
|
731
732
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
if (err) return done(err);
|
|
736
|
-
db.query('testcollection', {x: 5}, {x: true}, null, function(err, results) {
|
|
733
|
+
it('query does not return committed metadata by default with projection', function(done) {
|
|
734
|
+
var db = this.db;
|
|
735
|
+
commitSnapshotWithMetadata(db, function(err) {
|
|
737
736
|
if (err) return done(err);
|
|
738
|
-
|
|
739
|
-
|
|
737
|
+
db.query('testcollection', {x: 5}, {x: true}, null, function(err, results) {
|
|
738
|
+
if (err) return done(err);
|
|
739
|
+
expect(results[0].m).equal(null);
|
|
740
|
+
done();
|
|
741
|
+
});
|
|
740
742
|
});
|
|
741
743
|
});
|
|
742
|
-
});
|
|
743
744
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
if (err) return done(err);
|
|
748
|
-
db.query('testcollection', {x: 5}, {x: true}, {metadata: true}, function(err, results) {
|
|
745
|
+
it('query returns metadata when option is true with projection', function(done) {
|
|
746
|
+
var db = this.db;
|
|
747
|
+
commitSnapshotWithMetadata(db, function(err) {
|
|
749
748
|
if (err) return done(err);
|
|
750
|
-
|
|
751
|
-
|
|
749
|
+
db.query('testcollection', {x: 5}, {x: true}, {metadata: true}, function(err, results) {
|
|
750
|
+
if (err) return done(err);
|
|
751
|
+
expect(results[0].m).eql({test: 3});
|
|
752
|
+
done();
|
|
753
|
+
});
|
|
752
754
|
});
|
|
753
755
|
});
|
|
754
756
|
});
|
|
755
|
-
});
|
|
756
757
|
|
|
757
|
-
if (options.getQuery) {
|
|
758
758
|
describe('queryPoll', function() {
|
|
759
759
|
it('returns data in the collection', function(done) {
|
|
760
760
|
var snapshot = {v: 1, type: 'json0', data: {x: 5, y: 6}};
|