mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-11 19:11:10 -05:00
Add tests for type after mutations (#1753)
Also, remove invariant for set intersection. We can handle different types now. Fixes #1749
This commit is contained in:
@@ -795,3 +795,29 @@ func TestListDiffString3(t *testing.T) {
|
||||
}
|
||||
assert.Equal(diff2Expected, diff2, "expected diff is wrong")
|
||||
}
|
||||
|
||||
func TestListTypeAfterMutations(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
test := func(n int, c interface{}) {
|
||||
values := generateNumbersAsValues(n)
|
||||
|
||||
l := NewList(values...)
|
||||
assert.Equal(l.Len(), uint64(n))
|
||||
assert.IsType(c, l.sequence())
|
||||
assert.True(l.Type().Equals(MakeListType(NumberType)))
|
||||
|
||||
l = l.Append(NewString("a"))
|
||||
assert.Equal(l.Len(), uint64(n+1))
|
||||
assert.IsType(c, l.sequence())
|
||||
assert.True(l.Type().Equals(MakeListType(MakeUnionType(NumberType, StringType))))
|
||||
|
||||
l = l.Splice(l.Len()-1, 1)
|
||||
assert.Equal(l.Len(), uint64(n))
|
||||
assert.IsType(c, l.sequence())
|
||||
assert.True(l.Type().Equals(MakeListType(NumberType)))
|
||||
}
|
||||
|
||||
test(10, listLeafSequence{})
|
||||
test(100, indexedMetaSequence{})
|
||||
}
|
||||
|
||||
@@ -947,3 +947,33 @@ func TestMapModifyAfterRead(t *testing.T) {
|
||||
m = m.Set(fst, fstval)
|
||||
assert.True(m.Has(fst))
|
||||
}
|
||||
|
||||
func TestMapTypeAfterMutations(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
test := func(n int, c interface{}) {
|
||||
values := make([]Value, 2*n)
|
||||
for i := 0; i < n; i++ {
|
||||
values[2*i] = Number(i)
|
||||
values[2*i+1] = Number(i)
|
||||
}
|
||||
|
||||
m := NewMap(values...)
|
||||
assert.Equal(m.Len(), uint64(n))
|
||||
assert.IsType(c, m.sequence())
|
||||
assert.True(m.Type().Equals(MakeMapType(NumberType, NumberType)))
|
||||
|
||||
m = m.Set(NewString("a"), NewString("a"))
|
||||
assert.Equal(m.Len(), uint64(n+1))
|
||||
assert.IsType(c, m.sequence())
|
||||
assert.True(m.Type().Equals(MakeMapType(MakeUnionType(NumberType, StringType), MakeUnionType(NumberType, StringType))))
|
||||
|
||||
m = m.Remove(NewString("a"))
|
||||
assert.Equal(m.Len(), uint64(n))
|
||||
assert.IsType(c, m.sequence())
|
||||
assert.True(m.Type().Equals(MakeMapType(NumberType, NumberType)))
|
||||
}
|
||||
|
||||
test(10, mapLeafSequence{})
|
||||
test(100, orderedMetaSequence{})
|
||||
}
|
||||
|
||||
@@ -804,3 +804,29 @@ func TestSetModifyAfterRead(t *testing.T) {
|
||||
set = set.Insert(fst)
|
||||
assert.True(set.Has(fst))
|
||||
}
|
||||
|
||||
func TestSetTypeAfterMutations(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
test := func(n int, c interface{}) {
|
||||
values := generateNumbersAsValues(n)
|
||||
|
||||
s := NewSet(values...)
|
||||
assert.Equal(s.Len(), uint64(n))
|
||||
assert.IsType(c, s.sequence())
|
||||
assert.True(s.Type().Equals(MakeSetType(NumberType)))
|
||||
|
||||
s = s.Insert(NewString("a"))
|
||||
assert.Equal(s.Len(), uint64(n+1))
|
||||
assert.IsType(c, s.sequence())
|
||||
assert.True(s.Type().Equals(MakeSetType(MakeUnionType(NumberType, StringType))))
|
||||
|
||||
s = s.Remove(NewString("a"))
|
||||
assert.Equal(s.Len(), uint64(n))
|
||||
assert.IsType(c, s.sequence())
|
||||
assert.True(s.Type().Equals(MakeSetType(NumberType)))
|
||||
}
|
||||
|
||||
test(10, setLeafSequence{})
|
||||
test(100, orderedMetaSequence{})
|
||||
}
|
||||
|
||||
+28
-3
@@ -7,18 +7,19 @@
|
||||
import {assert} from 'chai';
|
||||
import {suite, setup, teardown, test} from 'mocha';
|
||||
|
||||
import List, {ListWriter} from './list.js';
|
||||
import List, {ListWriter, ListLeafSequence} from './list.js';
|
||||
import Ref from './ref.js';
|
||||
import {MetaTuple, newListMetaSequence} from './meta-sequence.js';
|
||||
import {calcSplices} from './edit-distance.js';
|
||||
import {equals} from './compare.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {newStruct} from './struct.js';
|
||||
|
||||
import {
|
||||
makeRefType,
|
||||
makeListType,
|
||||
makeRefType,
|
||||
makeUnionType,
|
||||
numberType,
|
||||
stringType,
|
||||
} from './type.js';
|
||||
import {
|
||||
assertChunkCountAndType,
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
testRoundTripAndValidate,
|
||||
} from './test-util.js';
|
||||
import TestDatabase from './test-database.js';
|
||||
import {IndexedMetaSequence} from './meta-sequence.js';
|
||||
|
||||
const testListSize = 5000;
|
||||
const listOfNRef = 'sha1-241e54086d50c131db3c2f3f5f17e68f42fd98ac';
|
||||
@@ -591,4 +593,27 @@ suite('ListWriter', () => {
|
||||
assert.strictEqual(l2, l3);
|
||||
});
|
||||
|
||||
test('Type after mutations', async () => {
|
||||
async function t(n, c) {
|
||||
const values: any = intSequence(n);
|
||||
|
||||
let l = new List(values);
|
||||
assert.equal(l.length, n);
|
||||
assert.instanceOf(l.sequence, c);
|
||||
assert.isTrue(equals(l.type, makeListType(numberType)));
|
||||
|
||||
l = await l.append('a');
|
||||
assert.equal(l.length, n + 1);
|
||||
assert.instanceOf(l.sequence, c);
|
||||
assert.isTrue(equals(l.type, makeListType(makeUnionType([numberType, stringType]))));
|
||||
|
||||
l = await l.splice(l.length - 1, 1);
|
||||
assert.equal(l.length, n);
|
||||
assert.instanceOf(l.sequence, c);
|
||||
assert.isTrue(equals(l.type, makeListType(numberType)));
|
||||
}
|
||||
|
||||
await t(10, ListLeafSequence);
|
||||
await t(100, IndexedMetaSequence);
|
||||
});
|
||||
});
|
||||
|
||||
+36
-1
@@ -16,11 +16,18 @@ import Struct, {newStruct} from './struct.js';
|
||||
import {flatten, flattenParallel, deriveCollectionHeight} from './test-util.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import Chunk from './chunk.js';
|
||||
import Map from './map.js';
|
||||
import Map, {MapLeafSequence} from './map.js';
|
||||
import {MetaTuple, newMapMetaSequence} from './meta-sequence.js';
|
||||
import Hash from './hash.js';
|
||||
import type {ValueReadWriter} from './value-store.js';
|
||||
import {compare, equals} from './compare.js';
|
||||
import {OrderedMetaSequence} from './meta-sequence.js';
|
||||
import {
|
||||
makeMapType,
|
||||
makeUnionType,
|
||||
numberType,
|
||||
stringType,
|
||||
} from './type.js';
|
||||
|
||||
const testMapSize = 1000;
|
||||
const mapOfNRef = 'sha1-9fce950ce2606ced8681a695b608384c642ffb53';
|
||||
@@ -658,4 +665,32 @@ suite('CompoundMap', () => {
|
||||
assert.deepEqual(sequence.items[0].ref, chunks[0]);
|
||||
assert.deepEqual(sequence.items[1].ref, chunks[1]);
|
||||
});
|
||||
|
||||
test('Type after mutations', async () => {
|
||||
async function t(n, c) {
|
||||
const values: any = new Array(n);
|
||||
for (let i = 0; i < n; i++) {
|
||||
values[i] = [i, i];
|
||||
}
|
||||
|
||||
let m = new Map(values);
|
||||
assert.equal(m.size, n);
|
||||
assert.instanceOf(m.sequence, c);
|
||||
assert.isTrue(equals(m.type, makeMapType(numberType, numberType)));
|
||||
|
||||
m = await m.set('a', 'a');
|
||||
assert.equal(m.size, n + 1);
|
||||
assert.instanceOf(m.sequence, c);
|
||||
assert.isTrue(equals(m.type, makeMapType(makeUnionType([numberType, stringType]),
|
||||
makeUnionType([numberType, stringType]))));
|
||||
|
||||
m = await m.remove('a');
|
||||
assert.equal(m.size, n);
|
||||
assert.instanceOf(m.sequence, c);
|
||||
assert.isTrue(equals(m.type, makeMapType(numberType, numberType)));
|
||||
}
|
||||
|
||||
await t(10, MapLeafSequence);
|
||||
await t(100, OrderedMetaSequence);
|
||||
});
|
||||
});
|
||||
|
||||
+68
-5
@@ -13,7 +13,7 @@ import Database from './database.js';
|
||||
import Hash from './hash.js';
|
||||
import MemoryStore from './memory-store.js';
|
||||
import Ref from './ref.js';
|
||||
import Set from './set.js';
|
||||
import Set, {SetLeafSequence} from './set.js';
|
||||
import type {ValueReadWriter} from './value-store.js';
|
||||
import {BatchStoreAdaptorDelegate, makeTestingBatchStore} from './batch-store-adaptor.js';
|
||||
import {MetaTuple, newSetMetaSequence} from './meta-sequence.js';
|
||||
@@ -22,6 +22,13 @@ import {compare, equals} from './compare.js';
|
||||
import {flatten, flattenParallel, intSequence, deriveCollectionHeight} from './test-util.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {newStruct} from './struct.js';
|
||||
import {OrderedMetaSequence} from './meta-sequence.js';
|
||||
import {
|
||||
makeSetType,
|
||||
makeUnionType,
|
||||
numberType,
|
||||
stringType,
|
||||
} from './type.js';
|
||||
|
||||
const testSetSize = 5000;
|
||||
const setOfNRef = 'sha1-1fc97c4e369770b643e013569c68687765601514';
|
||||
@@ -309,8 +316,8 @@ suite('SetLeaf', () => {
|
||||
test('chunks', () => {
|
||||
const refs = ['x', 'a', 'b'].map(c => db.writeValue(c));
|
||||
refs.sort(compare);
|
||||
const l = new Set(['z', ...refs]);
|
||||
assert.deepEqual(refs, l.chunks);
|
||||
const s = new Set(['z', ...refs]);
|
||||
assert.deepEqual(refs, s.chunks);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -328,8 +335,8 @@ suite('CompoundSet', () => {
|
||||
|
||||
let tuples = [];
|
||||
for (let i = 0; i < values.length; i += 2) {
|
||||
const l = new Set([values[i], values[i + 1]]);
|
||||
const r = vwr.writeValue(l);
|
||||
const s = new Set([values[i], values[i + 1]]);
|
||||
const r = vwr.writeValue(s);
|
||||
tuples.push(new MetaTuple(r, values[i + 1], 2, null));
|
||||
}
|
||||
|
||||
@@ -663,4 +670,60 @@ suite('CompoundSet', () => {
|
||||
assert.deepEqual(sequence.items[0].ref, chunks[0]);
|
||||
assert.deepEqual(sequence.items[1].ref, chunks[1]);
|
||||
});
|
||||
|
||||
test('Type after mutations', async () => {
|
||||
async function t(n, c) {
|
||||
const values: any = intSequence(n);
|
||||
|
||||
let s = new Set(values);
|
||||
assert.equal(s.size, n);
|
||||
assert.instanceOf(s.sequence, c);
|
||||
assert.isTrue(equals(s.type, makeSetType(numberType)));
|
||||
|
||||
s = await s.insert('a');
|
||||
assert.equal(s.size, n + 1);
|
||||
assert.instanceOf(s.sequence, c);
|
||||
assert.isTrue(equals(s.type, makeSetType(makeUnionType([numberType, stringType]))));
|
||||
|
||||
s = await s.remove('a');
|
||||
assert.equal(s.size, n);
|
||||
assert.instanceOf(s.sequence, c);
|
||||
assert.isTrue(equals(s.type, makeSetType(numberType)));
|
||||
}
|
||||
|
||||
await t(10, SetLeafSequence);
|
||||
await t(100, OrderedMetaSequence);
|
||||
});
|
||||
|
||||
test('Type after mutations - interesect', async () => {
|
||||
async function t(n, c) {
|
||||
const nums: any = intSequence(n);
|
||||
const strings = nums.map(n => String.fromCodePoint(n));
|
||||
const combined = nums.concat(strings);
|
||||
|
||||
const numSet = new Set(nums);
|
||||
assert.equal(numSet.size, n);
|
||||
assert.instanceOf(numSet.sequence, c);
|
||||
assert.isTrue(equals(numSet.type, makeSetType(numberType)));
|
||||
|
||||
const stringSet = new Set(strings);
|
||||
assert.equal(stringSet.size, n);
|
||||
assert.instanceOf(stringSet.sequence, c);
|
||||
assert.isTrue(equals(stringSet.type, makeSetType(stringType)));
|
||||
|
||||
const combinedSet = new Set(combined);
|
||||
assert.equal(combinedSet.size, 2 * n);
|
||||
assert.instanceOf(combinedSet.sequence, c);
|
||||
assert.isTrue(equals(combinedSet.type, makeSetType(makeUnionType([numberType, stringType]))));
|
||||
|
||||
const s = await combinedSet.intersect(numSet);
|
||||
assert.isTrue(equals(s, numSet));
|
||||
|
||||
const s2 = await combinedSet.intersect(stringSet);
|
||||
assert.isTrue(equals(s2, stringSet));
|
||||
}
|
||||
|
||||
await t(10, SetLeafSequence);
|
||||
await t(100, OrderedMetaSequence);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -159,11 +159,6 @@ export default class Set<T: Value> extends Collection<OrderedSequence> {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Can't intersect sets of different element type.
|
||||
for (let i = 0; i < sets.length; i++) {
|
||||
invariant(equals(sets[i].type, this.type));
|
||||
}
|
||||
|
||||
let cursor = await this.sequence.newCursorAt(null);
|
||||
if (!cursor.valid) {
|
||||
return this;
|
||||
|
||||
Reference in New Issue
Block a user