Skip to content

Commit 5687094

Browse files
committed
Add unit test demonstrating that patch and incrementalPatch do not work for deeply nested values
1 parent 0cdcbe1 commit 5687094

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

test/unit.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,5 @@ import './unit/import-export.test.ts';
7070
import './unit/database-lifecycle.ts';
7171
import './unit/plugin.test.ts';
7272
import './unit/last.test.ts';
73+
import './unit/deep-incremental-patch.test.ts';
74+
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/**
2+
* Tests that `patch` and `incrementalPatch` can patch objects with deeply nested values without splicing out other values.
3+
*/
4+
import assert from 'assert';
5+
import AsyncTestUtil from 'async-test-util';
6+
import config from './config.ts';
7+
8+
import {
9+
createRxDatabase,
10+
randomToken
11+
} from '../../plugins/core/index.mjs';
12+
13+
describe('deep-incremental-patch.test.js', () => {
14+
it('should incrementally patch deeply nested values without splicing out other value', async function () {
15+
if (!config.storage.hasMultiInstance) {
16+
return;
17+
}
18+
19+
// create a schema
20+
const mySchema = {
21+
version: 0,
22+
primaryKey: 'passportId',
23+
type: 'object',
24+
properties: {
25+
passportId: {
26+
type: 'string',
27+
maxLength: 100
28+
},
29+
data: {
30+
type: 'object',
31+
properties: {
32+
firstName: {
33+
type: 'string'
34+
},
35+
lastName: {
36+
type: 'string'
37+
},
38+
age: {
39+
type: 'integer',
40+
minimum: 0,
41+
maximum: 150
42+
},
43+
deep: {
44+
type: 'object',
45+
properties: {
46+
value: {
47+
type: 'boolean'
48+
}
49+
}
50+
}
51+
}
52+
}
53+
}
54+
};
55+
56+
/**
57+
* Always generate a random database-name
58+
* to ensure that different test runs do not affect each other.
59+
*/
60+
const name = randomToken(10);
61+
62+
// create a database
63+
const db = await createRxDatabase({
64+
name,
65+
/**
66+
* By calling config.storage.getStorage(),
67+
* we can ensure that all variations of RxStorage are tested in the CI.
68+
*/
69+
storage: config.storage.getStorage(),
70+
eventReduce: true,
71+
ignoreDuplicate: true
72+
});
73+
// create a collection
74+
const collections = await db.addCollections({
75+
mycollection: {
76+
schema: mySchema
77+
}
78+
});
79+
80+
// insert a document
81+
await collections.mycollection.insert({
82+
passportId: 'foobar',
83+
data: {
84+
firstName: 'Bob',
85+
lastName: 'Kelso',
86+
age: 56,
87+
deep: {
88+
value: true
89+
}
90+
}
91+
92+
});
93+
94+
/**
95+
* to simulate the event-propagation over multiple browser-tabs,
96+
* we create the same database again
97+
*/
98+
const dbInOtherTab = await createRxDatabase({
99+
name,
100+
storage: config.storage.getStorage(),
101+
eventReduce: true,
102+
ignoreDuplicate: true
103+
});
104+
// create a collection
105+
const collectionInOtherTab = await dbInOtherTab.addCollections({
106+
mycollection: {
107+
schema: mySchema
108+
}
109+
});
110+
111+
// find the document in the other tab
112+
let myDocument = await collectionInOtherTab.mycollection
113+
.findOne()
114+
.where('passportId')
115+
.eq('foobar')
116+
.exec();
117+
118+
myDocument = await myDocument.incrementalPatch({
119+
data: {
120+
firstName: 'RxDb Developer'
121+
}
122+
});
123+
124+
/*
125+
* assert things,
126+
* here your tests should fail to show that there is a bug
127+
*/
128+
assert.strictEqual(myDocument.data.firstName, 'RxDb Developer');
129+
130+
// These would fail pre-change.
131+
assert.strictEqual(myDocument.data.lastName, 'Kelso');
132+
assert.strictEqual(myDocument.data.age, 56);
133+
assert.strictEqual(myDocument.data.deep.value, true);
134+
135+
136+
myDocument = await myDocument.patch({
137+
data: {
138+
deep: {
139+
value: false
140+
}
141+
}
142+
});
143+
assert.strictEqual(myDocument.data.deep.value, false);
144+
145+
// These would fail pre-change.
146+
assert.strictEqual(myDocument.data.firstName, 'RxDb Developer');
147+
assert.strictEqual(myDocument.data.lastName, 'Kelso');
148+
assert.strictEqual(myDocument.data.age, 56);
149+
150+
151+
152+
// you can also wait for events
153+
const emitted: any[] = [];
154+
const sub = collectionInOtherTab.mycollection
155+
.findOne().$
156+
.subscribe(doc => {
157+
emitted.push(doc);
158+
});
159+
await AsyncTestUtil.waitUntil(() => emitted.length === 1);
160+
161+
// clean up afterwards
162+
sub.unsubscribe();
163+
db.close();
164+
dbInOtherTab.close();
165+
});
166+
});

0 commit comments

Comments
 (0)