utilTest function

List<dynamic Function(FoodbTestContext)> utilTest()

Implementation

List<Function(FoodbTestContext)> utilTest() {
  return [
    (FoodbTestContext ctx) {
      test('info()', () async {
        final db = await ctx.db('test-info');
        var doc1 = await db.put(doc: Doc(id: 'a', model: {}));
        await db.put(doc: Doc(id: 'b', model: {}));
        await db.delete(id: doc1.id, rev: doc1.rev);
        var result = await db.info();
        expect(result, isNotNull);
        expect(result.dbName.endsWith('test-info'), true);
        expect(result.docCount, 1);
      });
    },
    (FoodbTestContext ctx) {
      test('EnsureFullCommit In CouchDB adish', () async {
        final db = await ctx.db('ensure-commit');
        var ensureFullCommitResponse = await db.ensureFullCommit();
        expect(ensureFullCommitResponse.ok, isTrue);
      });
    },
    (FoodbTestContext ctx) {
      test('delete db', () async {
        final db = await ctx.db('destroy');
        await db.destroy();
        try {
          await db.info();
        } catch (err) {
          expectAsync0(() => expect(err, isA<AdapterException>()))();
        }
      });
    },
    (FoodbTestContext ctx) {
      test('revsDiff', () async {
        final db = await ctx.db('revs-diff');
        await db.put(
            doc: Doc(id: 'a', rev: Rev.fromString('1-a'), model: {}),
            newEdits: false);
        await db.put(
            doc: Doc(
                id: 'a',
                rev: Rev.fromString('2-a'),
                revisions: Revisions(start: 2, ids: ['a', 'a']),
                model: {}),
            newEdits: false);
        await db.put(
            doc: Doc(
                id: 'a',
                rev: Rev.fromString('3-a'),
                revisions: Revisions(start: 3, ids: ['a', 'a', 'a']),
                model: {}),
            newEdits: false);

        var revsDiff = await db.revsDiff(body: {
          'a': [
            Rev.fromString('1-a'),
            Rev.fromString('2-a'),
            Rev.fromString('3-a'),
            Rev.fromString('4-a'),
            Rev.fromString('5-a')
          ]
        });
        expect(revsDiff['a']!.missing.length, 2);
      });
    },
    (FoodbTestContext ctx) {
      test('rev limit and compaction', () async {
        final db = await ctx.db('rev-limit-and-compaction');
        putDoc(List<String> revs) {
          var revisions = Revisions(
            start: int.parse(revs[0].split('-')[0]),
            ids: revs.map((e) => e.split('-')[1]).toList(),
          );
          var rev = Rev.fromString(revs[0]);
          return db.put(
              doc: Doc(
                id: 'a',
                rev: rev,
                model: {},
                revisions: revisions,
              ),
              newEdits: false);
        }

        getDoc([String? rev]) {
          return db.get(
            id: 'a',
            fromJsonT: (json) => json,
            rev: rev,
            revsInfo: true,
            revs: true,
            conflicts: true,
            meta: true,
          );
        }

        await putDoc(['1-a']);
        await putDoc(['2-a', '1-a']);
        await putDoc(['3-a', '2-a', '1-a']);
        await putDoc(['4-a', '3-a', '2-a', '1-a']);
        await putDoc(['3-b', '2-a', '1-a']);
        await putDoc(['4-b', '3-b', '2-a', '1-a']);
        // rev limit will not remove revinfos, just change revisions ouput, doc still exist
        await db.revsLimit(2);
        var winner = await getDoc();
        expect(winner, isNotNull);
        expect(winner.conflicts, hasLength(1));
        expect(winner.revsInfo, hasLength(4));
        expect(winner.revisions!.ids, hasLength(2));

        var winnerUsingRev = await getDoc('4-b');
        expect(winnerUsingRev, isNotNull);
        expect(winnerUsingRev.revsInfo, isNull);

        var winnerBranch = await getDoc('3-b');
        expect(winnerBranch, isNotNull);
        expect(winnerBranch.revsInfo, isNull);
        expect(winnerBranch.revisions!.ids, hasLength(2));

        var commonAccestor = await getDoc('2-a');
        expect(commonAccestor, isNotNull);
        expect(commonAccestor.revsInfo, isNull);
        expect(commonAccestor.revisions!.ids, hasLength(2));

        var conflictLeaf = await getDoc('4-a');
        expect(conflictLeaf, isNotNull);
        expect(conflictLeaf.revsInfo, isNull);
        expect(conflictLeaf.revisions!.ids, hasLength(2));

        var conflictBranch = await getDoc('3-a');
        expect(conflictBranch, isNotNull);
        expect(conflictBranch.revsInfo, isNull);
        expect(conflictBranch.revisions!.ids, hasLength(2));

        // compact before rev limit will not reduce revisions.ids, doc disappear
        await db.revsLimit(100);
        await db.compact();
        await Future.delayed(Duration(seconds: 1));
        winner = await getDoc();
        expect(winner, isNotNull);
        expect(winner.revisions!.ids, hasLength(4));

        var winnerBranch2 = getDoc('3-b');
        await expectLater(
            winnerBranch2,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));

        var commonAccestor2 = getDoc('2-a');
        await expectLater(
            commonAccestor2,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));

        conflictLeaf = await getDoc('4-a');
        expect(conflictLeaf, isNotNull);
        expect(conflictLeaf.revisions!.ids, hasLength(4));

        var conflictBranch2 = getDoc('3-a');
        await expectLater(
            conflictBranch2,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));

        // compact after change rev limit, revisions id dissappear
        await db.revsLimit(2);
        await db.compact();
        await Future.delayed(Duration(seconds: 1));
        winner = await getDoc();
        conflictLeaf = await getDoc('4-a');
        expect(winner.revsInfo, hasLength(2));
        expect(winner.revisions!.ids, hasLength(2));
        expect(conflictLeaf.revisions!.ids, hasLength(2));

        // changing rev limit will rerun compacting since start
        await putDoc(['5-b', '4-b', '3-b', '2-a', '1-a']);
        await db.revsLimit(1);
        await db.compact();
        await Future.delayed(Duration(seconds: 1));
        winner = await getDoc();
        expect(winner.revsInfo, hasLength(1));
        expect(winner.revisions!.ids, hasLength(1));
      });
    },
    (FoodbTestContext ctx) {
      test('rev limit and auto compaction', () async {
        final db =
            await ctx.db('rev-limit-and-auto-compaction', autoCompaction: true);
        putDoc(List<String> revs) {
          var revisions = Revisions(
            start: int.parse(revs[0].split('-')[0]),
            ids: revs.map((e) => e.split('-')[1]).toList(),
          );
          var rev = Rev.fromString(revs[0]);
          return db.put(
              doc: Doc(
                id: 'a',
                rev: rev,
                model: {},
                revisions: revisions,
              ),
              newEdits: false);
        }

        getDoc([String? rev]) {
          return db.get(
            id: 'a',
            fromJsonT: (json) => json,
            rev: rev,
            revsInfo: true,
            revs: true,
            conflicts: true,
            meta: true,
          );
        }

        await db.revsLimit(2);
        await putDoc(['1-a']);
        await putDoc(['2-a', '1-a']);
        await putDoc(['3-a', '2-a', '1-a']);
        await putDoc(['4-a', '3-a', '2-a', '1-a']);
        await putDoc(['3-b', '2-a', '1-a']);
        await putDoc(['4-b', '3-b', '2-a', '1-a']);
        if (ctx is CouchdbTestContext) {
          await db.compact();
        }
        await Future.delayed(Duration(seconds: 1));
        var winner = await getDoc();
        expect(winner, isNotNull);
        expect(winner.revisions!.ids, hasLength(2));

        var winnerBranch = getDoc('3-b');
        await expectLater(
            winnerBranch,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));

        var commonAccestor = getDoc('2-a');
        await expectLater(
            commonAccestor,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));

        var conflictLeaf = await getDoc('4-a');
        expect(conflictLeaf, isNotNull);
        expect(conflictLeaf.revisions!.ids, hasLength(2));

        var conflictBranch = getDoc('3-a');
        await expectLater(
            conflictBranch,
            throwsA(predicate((e) =>
                e is AdapterException && e.reason!.contains('missing'))));
      });
    },
  ];
}