sharedb 3.2.4 → 3.3.1
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/agent.js +2 -1
- package/lib/backend.js +44 -7
- package/lib/client/doc.js +18 -0
- package/lib/error.js +4 -0
- package/lib/message-actions.js +1 -0
- package/lib/query-emitter.js +34 -23
- package/lib/submit-request.js +45 -1
- package/package.json +2 -2
- package/test/client/presence/presence.js +0 -25
- package/test/client/query-subscribe.js +781 -493
- package/test/client/submit.js +48 -0
- package/test/logger.js +0 -4
- package/test/middleware.js +356 -0
- package/test/milestone-db.js +8 -4
- package/test/setup.js +5 -0
package/test/client/submit.js
CHANGED
|
@@ -4,6 +4,7 @@ var sinon = require('sinon');
|
|
|
4
4
|
var types = require('../../lib/types');
|
|
5
5
|
var deserializedType = require('./deserialized-type');
|
|
6
6
|
var numberType = require('./number-type');
|
|
7
|
+
var errorHandler = require('../util').errorHandler;
|
|
7
8
|
types.register(deserializedType.type);
|
|
8
9
|
types.register(deserializedType.type2);
|
|
9
10
|
types.register(numberType.type);
|
|
@@ -1210,5 +1211,52 @@ module.exports = function() {
|
|
|
1210
1211
|
});
|
|
1211
1212
|
});
|
|
1212
1213
|
});
|
|
1214
|
+
|
|
1215
|
+
describe('submitting when behind the server', function() {
|
|
1216
|
+
var doc;
|
|
1217
|
+
var remoteDoc;
|
|
1218
|
+
|
|
1219
|
+
beforeEach(function(done) {
|
|
1220
|
+
var connection = this.backend.connect();
|
|
1221
|
+
doc = connection.get('dogs', 'fido');
|
|
1222
|
+
var remoteConnection = this.backend.connect();
|
|
1223
|
+
remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
1224
|
+
|
|
1225
|
+
async.series([
|
|
1226
|
+
doc.create.bind(doc, {name: 'fido'}),
|
|
1227
|
+
remoteDoc.fetch.bind(remoteDoc),
|
|
1228
|
+
remoteDoc.submitOp.bind(remoteDoc, [{p: ['tricks'], oi: ['fetch']}]),
|
|
1229
|
+
function(next) {
|
|
1230
|
+
expect(doc.data).to.eql({name: 'fido'});
|
|
1231
|
+
expect(remoteDoc.data).to.eql({name: 'fido', tricks: ['fetch']});
|
|
1232
|
+
next();
|
|
1233
|
+
}
|
|
1234
|
+
], done);
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
it('is sent ops it has missed when submitting, without calling fetch', function(done) {
|
|
1238
|
+
sinon.spy(doc, 'fetch');
|
|
1239
|
+
|
|
1240
|
+
doc.submitOp([{p: ['age'], oi: 2}], errorHandler(done));
|
|
1241
|
+
|
|
1242
|
+
doc.once('op', function() {
|
|
1243
|
+
expect(doc.data).to.eql({name: 'fido', tricks: ['fetch'], age: 2});
|
|
1244
|
+
expect(doc.fetch.called).to.be.false;
|
|
1245
|
+
done();
|
|
1246
|
+
});
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
it('does not expose op metadata in the middleware when sending missing ops', function(done) {
|
|
1250
|
+
this.backend.use('apply', function(request) {
|
|
1251
|
+
expect(request.ops).to.have.length(1);
|
|
1252
|
+
var op = request.ops[0];
|
|
1253
|
+
expect(op.op).to.eql([{p: ['tricks'], oi: ['fetch']}]);
|
|
1254
|
+
expect(op.m).to.be.undefined;
|
|
1255
|
+
done();
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
doc.submitOp([{p: ['age'], oi: 2}], errorHandler(done));
|
|
1259
|
+
});
|
|
1260
|
+
});
|
|
1213
1261
|
});
|
|
1214
1262
|
};
|
package/test/logger.js
CHANGED
package/test/middleware.js
CHANGED
|
@@ -3,6 +3,11 @@ var expect = require('chai').expect;
|
|
|
3
3
|
var util = require('./util');
|
|
4
4
|
var types = require('../lib/types');
|
|
5
5
|
var errorHandler = util.errorHandler;
|
|
6
|
+
var ShareDBError = require('../lib/error');
|
|
7
|
+
var sinon = require('sinon');
|
|
8
|
+
var ACTIONS = require('../lib/message-actions').ACTIONS;
|
|
9
|
+
|
|
10
|
+
var ERROR_CODE = ShareDBError.CODES;
|
|
6
11
|
|
|
7
12
|
describe('middleware', function() {
|
|
8
13
|
beforeEach(function() {
|
|
@@ -417,4 +422,355 @@ describe('middleware', function() {
|
|
|
417
422
|
doc.submitOp([{p: ['tricks', 1], li: 'stay'}], {source: 'c'}, errorHandler(done));
|
|
418
423
|
});
|
|
419
424
|
});
|
|
425
|
+
|
|
426
|
+
describe('$fixup', function() {
|
|
427
|
+
var connection;
|
|
428
|
+
var backend;
|
|
429
|
+
var doc;
|
|
430
|
+
|
|
431
|
+
beforeEach(function(done) {
|
|
432
|
+
backend = this.backend;
|
|
433
|
+
connection = backend.connect();
|
|
434
|
+
doc = connection.get('dogs', 'fido');
|
|
435
|
+
|
|
436
|
+
doc.create({name: 'fido'}, done);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('applies a fixup op to the client that submitted it', function(done) {
|
|
440
|
+
backend.use('apply', function(request, next) {
|
|
441
|
+
request.$fixup([{p: ['tricks', 1], li: 'stay'}]);
|
|
442
|
+
next();
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], function(error) {
|
|
446
|
+
if (error) return done(error);
|
|
447
|
+
expect(doc.data.tricks).to.eql(['fetch', 'stay']);
|
|
448
|
+
expect(doc.version).to.equal(2);
|
|
449
|
+
done();
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('emits an op event for the fixup', function(done) {
|
|
454
|
+
backend.use('apply', function(request, next) {
|
|
455
|
+
request.$fixup([{p: ['tricks', 1], li: 'stay'}]);
|
|
456
|
+
next();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], errorHandler(done));
|
|
460
|
+
|
|
461
|
+
doc.on('op', function() {
|
|
462
|
+
expect(doc.data.tricks).to.eql(['fetch', 'stay']);
|
|
463
|
+
done();
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it('passes the fixed up op to future middleware', function(done) {
|
|
468
|
+
backend.use('apply', function(request, next) {
|
|
469
|
+
request.$fixup([{p: ['tricks', 1], li: 'stay'}]);
|
|
470
|
+
next();
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
backend.use('apply', function(request, next) {
|
|
474
|
+
expect(request.op.op).to.eql([
|
|
475
|
+
{p: ['tricks'], oi: ['fetch']},
|
|
476
|
+
{p: ['tricks', 1], li: 'stay'}
|
|
477
|
+
]);
|
|
478
|
+
next();
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], done);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it('applies the composed op to a remote client', function(done) {
|
|
485
|
+
backend.use('apply', function(request, next) {
|
|
486
|
+
request.$fixup([{p: ['tricks', 1], li: 'stay'}]);
|
|
487
|
+
next();
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
var remoteConnection = backend.connect();
|
|
491
|
+
var remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
492
|
+
|
|
493
|
+
remoteDoc.subscribe(function(error) {
|
|
494
|
+
if (error) return done(error);
|
|
495
|
+
|
|
496
|
+
expect(remoteDoc.data).to.eql({name: 'fido'});
|
|
497
|
+
|
|
498
|
+
remoteDoc.on('op batch', function() {
|
|
499
|
+
expect(remoteDoc.data.tricks).to.eql(['fetch', 'stay']);
|
|
500
|
+
expect(doc.version).to.equal(remoteDoc.version);
|
|
501
|
+
done();
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], errorHandler(done));
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('transforms pending ops by the fixup for remote clients', function(done) {
|
|
509
|
+
var applied = false;
|
|
510
|
+
backend.use('apply', function(request, next) {
|
|
511
|
+
if (applied) return next();
|
|
512
|
+
applied = true;
|
|
513
|
+
request.$fixup([{p: ['tricks', 0], li: 'stay'}]);
|
|
514
|
+
next();
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
var remoteConnection = backend.connect();
|
|
518
|
+
var remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
519
|
+
|
|
520
|
+
remoteDoc.subscribe(function(error) {
|
|
521
|
+
if (error) return done(error);
|
|
522
|
+
|
|
523
|
+
expect(remoteDoc.data).to.eql({name: 'fido'});
|
|
524
|
+
|
|
525
|
+
remoteDoc.on('op batch', function() {
|
|
526
|
+
if (remoteDoc.version !== 3) return;
|
|
527
|
+
expect(remoteDoc.data.tricks).to.eql(['stay', 'fetch', 'sit']);
|
|
528
|
+
expect(remoteDoc.data).to.eql(doc.data);
|
|
529
|
+
done();
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
doc.preventCompose = true;
|
|
533
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], errorHandler(done));
|
|
534
|
+
doc.submitOp([{p: ['tricks', 1], li: 'sit'}], errorHandler(done));
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it('transforms pending ops by the fixup for the local doc', function(done) {
|
|
539
|
+
var applied = false;
|
|
540
|
+
backend.use('apply', function(request, next) {
|
|
541
|
+
if (applied) return next();
|
|
542
|
+
applied = true;
|
|
543
|
+
request.$fixup([{p: ['tricks', 0, 0], si: 'go '}]);
|
|
544
|
+
next();
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
var remoteConnection = backend.connect();
|
|
548
|
+
var remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
549
|
+
|
|
550
|
+
remoteDoc.subscribe(function(error) {
|
|
551
|
+
if (error) return done(error);
|
|
552
|
+
|
|
553
|
+
expect(remoteDoc.data).to.eql({name: 'fido'});
|
|
554
|
+
|
|
555
|
+
remoteDoc.on('op batch', function() {
|
|
556
|
+
if (remoteDoc.version !== 3) return;
|
|
557
|
+
expect(remoteDoc.data.tricks).to.eql(['stay', 'go fetch']);
|
|
558
|
+
expect(remoteDoc.data).to.eql(doc.data);
|
|
559
|
+
done();
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
doc.preventCompose = true;
|
|
563
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch', 'stay']}], errorHandler(done));
|
|
564
|
+
doc.submitOp([{p: ['tricks', 0], lm: 1}], errorHandler(done));
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
it('applies a fixup to a creation op', function(done) {
|
|
569
|
+
backend.use('apply', function(request, next) {
|
|
570
|
+
request.$fixup([{p: ['goodBoy'], oi: true}]);
|
|
571
|
+
next();
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
doc = connection.get('dogs', 'rover');
|
|
575
|
+
doc.create({name: 'rover'}, function(error) {
|
|
576
|
+
if (error) return done(error);
|
|
577
|
+
expect(doc.data.goodBoy).to.be.true;
|
|
578
|
+
done();
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it('throws an error if trying to fixup a deletion', function(done) {
|
|
583
|
+
backend.use('apply', function(request, next) {
|
|
584
|
+
var error;
|
|
585
|
+
try {
|
|
586
|
+
request.$fixup([{p: ['tricks', 0], oi: ['stay']}]);
|
|
587
|
+
} catch (e) {
|
|
588
|
+
error = e;
|
|
589
|
+
}
|
|
590
|
+
next(error);
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
doc.del(function(error) {
|
|
594
|
+
expect(error.code).to.equal(ERROR_CODE.ERR_CANNOT_FIXUP_DELETION);
|
|
595
|
+
done();
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
it('throws an error if trying to fixup in commit middleware', function(done) {
|
|
600
|
+
backend.use('commit', function(request, next) {
|
|
601
|
+
var error;
|
|
602
|
+
try {
|
|
603
|
+
request.$fixup([{p: ['tricks', 0], oi: ['stay']}]);
|
|
604
|
+
} catch (e) {
|
|
605
|
+
error = e;
|
|
606
|
+
}
|
|
607
|
+
next(error);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
doc.submitOp([{p: ['goodBoy'], oi: true}], function(error) {
|
|
611
|
+
expect(error.code).to.equal(ERROR_CODE.ERR_FIXUP_IS_ONLY_VALID_ON_APPLY);
|
|
612
|
+
done();
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it('retry fixup', function(done) {
|
|
617
|
+
var flush;
|
|
618
|
+
backend.use('apply', function(request, next) {
|
|
619
|
+
expect(request.op.m.fixup).to.be.undefined;
|
|
620
|
+
if (flush) return next();
|
|
621
|
+
flush = function() {
|
|
622
|
+
request.$fixup([{p: ['name', 0], si: 'fixup'}]);
|
|
623
|
+
next();
|
|
624
|
+
};
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
doc.subscribe(function(error) {
|
|
628
|
+
if (error) return done(error);
|
|
629
|
+
|
|
630
|
+
var remoteConnection = backend.connect();
|
|
631
|
+
var remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
632
|
+
|
|
633
|
+
doc.submitOp([{p: ['name', 0], si: 'foo'}], function(error) {
|
|
634
|
+
if (error) return done(error);
|
|
635
|
+
expect(doc.data).to.eql({});
|
|
636
|
+
done();
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
remoteDoc.subscribe(function(error) {
|
|
640
|
+
if (error) return done(error);
|
|
641
|
+
remoteDoc.submitOp([{p: ['name'], od: 'fido'}], errorHandler(done));
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
doc.once('op', function(op, source) {
|
|
645
|
+
if (source) return;
|
|
646
|
+
expect(doc.data).to.eql({});
|
|
647
|
+
flush();
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
it('fixup that ignores no-op', function(done) {
|
|
653
|
+
var flush;
|
|
654
|
+
backend.use('apply', function(request, next) {
|
|
655
|
+
if (request.op.src !== connection.id) return next();
|
|
656
|
+
if (flush) {
|
|
657
|
+
request.$fixup([{p: ['name'], oi: 'fixup'}]);
|
|
658
|
+
return next();
|
|
659
|
+
}
|
|
660
|
+
flush = function() {
|
|
661
|
+
request.$fixup([{p: ['name', 0], si: 'fixup'}]);
|
|
662
|
+
next();
|
|
663
|
+
};
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
doc.subscribe(function(error) {
|
|
667
|
+
if (error) return done(error);
|
|
668
|
+
|
|
669
|
+
var remoteConnection = backend.connect();
|
|
670
|
+
var remoteDoc = remoteConnection.get('dogs', 'fido');
|
|
671
|
+
|
|
672
|
+
var count = 0;
|
|
673
|
+
var callback = function() {
|
|
674
|
+
count++;
|
|
675
|
+
if (count !== 2) return;
|
|
676
|
+
expect(doc.data).to.eql({name: 'fixup'});
|
|
677
|
+
expect(remoteDoc.data).to.eql(doc.data);
|
|
678
|
+
expect(doc.version).to.equal(remoteDoc.version);
|
|
679
|
+
done();
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
doc.submitOp([{p: ['name', 0], si: 'foo'}], function(error) {
|
|
683
|
+
if (error) return done(error);
|
|
684
|
+
callback();
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
remoteDoc.on('op', function(op, source) {
|
|
688
|
+
if (source) return;
|
|
689
|
+
callback();
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
remoteDoc.subscribe(function(error) {
|
|
693
|
+
if (error) return done(error);
|
|
694
|
+
remoteDoc.submitOp([{p: ['name'], od: 'fido'}], errorHandler(done));
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
doc.once('op', function(op, source) {
|
|
698
|
+
if (source) return;
|
|
699
|
+
expect(doc.data).to.eql({});
|
|
700
|
+
flush();
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('applies two fixups', function(done) {
|
|
706
|
+
backend.use('apply', function(request, next) {
|
|
707
|
+
request.$fixup([{p: ['tricks', 0], li: 'sit'}]);
|
|
708
|
+
next();
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
backend.use('apply', function(request, next) {
|
|
712
|
+
request.$fixup([{p: ['tricks', 0], li: 'stay'}]);
|
|
713
|
+
next();
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
doc.submitOp([{p: ['tricks'], oi: ['fetch']}], function(error) {
|
|
717
|
+
if (error) return done(error);
|
|
718
|
+
expect(doc.data.tricks).to.eql(['stay', 'sit', 'fetch']);
|
|
719
|
+
done();
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
it('rolls the doc back if the fixup cannot be applied', function(done) {
|
|
724
|
+
backend.use('apply', function(request, next) {
|
|
725
|
+
request.$fixup([{p: ['stay'], oi: true}]);
|
|
726
|
+
next();
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
backend.use('reply', function(request, next) {
|
|
730
|
+
if (request.reply[ACTIONS.fixup]) {
|
|
731
|
+
// Deliberately overwrite our fixup op to trigger a client rollback
|
|
732
|
+
request.reply[ACTIONS.fixup][0].op = [{p: ['fetch'], ld: 'bad'}];
|
|
733
|
+
}
|
|
734
|
+
next();
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
sinon.spy(doc, 'fetch');
|
|
738
|
+
|
|
739
|
+
doc.submitOp([{p: ['fetch'], oi: true}], function(error) {
|
|
740
|
+
expect(error).to.be.ok;
|
|
741
|
+
expect(doc.fetch.calledOnce).to.be.true;
|
|
742
|
+
done();
|
|
743
|
+
});
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
describe('no compose', function() {
|
|
747
|
+
var originalCompose;
|
|
748
|
+
|
|
749
|
+
beforeEach(function() {
|
|
750
|
+
originalCompose = types.defaultType.compose;
|
|
751
|
+
delete types.defaultType.compose;
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
afterEach(function() {
|
|
755
|
+
types.defaultType.compose = originalCompose.bind(types.defaultType);
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('throws an error if trying to compose on a type that does not support it', function(done) {
|
|
759
|
+
backend.use('apply', function(request, next) {
|
|
760
|
+
var error;
|
|
761
|
+
try {
|
|
762
|
+
request.$fixup([{p: ['tricks', 0], oi: ['stay']}]);
|
|
763
|
+
} catch (e) {
|
|
764
|
+
error = e;
|
|
765
|
+
}
|
|
766
|
+
next(error);
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
doc.submitOp([{p: ['goodBoy'], oi: true}], function(error) {
|
|
770
|
+
expect(error.code).to.equal(ERROR_CODE.ERR_TYPE_DOES_NOT_SUPPORT_COMPOSE);
|
|
771
|
+
done();
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
});
|
|
420
776
|
});
|
package/test/milestone-db.js
CHANGED
|
@@ -576,8 +576,10 @@ module.exports = function(options) {
|
|
|
576
576
|
});
|
|
577
577
|
|
|
578
578
|
it('only stores even-numbered versions', function(done) {
|
|
579
|
-
|
|
580
|
-
|
|
579
|
+
var snapshotCount = 0;
|
|
580
|
+
db.on('save', function() {
|
|
581
|
+
snapshotCount++;
|
|
582
|
+
if (snapshotCount < 2) return;
|
|
581
583
|
|
|
582
584
|
async.waterfall([
|
|
583
585
|
db.getMilestoneSnapshot.bind(db, 'books', 'catcher-in-the-rye', 1),
|
|
@@ -619,8 +621,10 @@ module.exports = function(options) {
|
|
|
619
621
|
callback();
|
|
620
622
|
});
|
|
621
623
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
+
var snapshotCount = 0;
|
|
625
|
+
db.on('save', function() {
|
|
626
|
+
snapshotCount++;
|
|
627
|
+
if (snapshotCount < 2) return;
|
|
624
628
|
|
|
625
629
|
async.waterfall([
|
|
626
630
|
db.getMilestoneSnapshot.bind(db, 'books', 'catcher-in-the-rye', 1),
|
package/test/setup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
var logger = require('../lib/logger');
|
|
2
|
+
var sinon = require('sinon');
|
|
2
3
|
|
|
3
4
|
if (process.env.LOGGING !== 'true') {
|
|
4
5
|
// Silence the logger for tests by setting all its methods to no-ops
|
|
@@ -8,3 +9,7 @@ if (process.env.LOGGING !== 'true') {
|
|
|
8
9
|
error: function() {}
|
|
9
10
|
});
|
|
10
11
|
}
|
|
12
|
+
|
|
13
|
+
afterEach(function() {
|
|
14
|
+
sinon.restore();
|
|
15
|
+
});
|