@model-ts/dynamodb 3.1.0 → 4.1.0
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/CHANGELOG.md +12 -0
- package/dist/cjs/__test__/client-with-cursor-encryption.test.js +1241 -1343
- package/dist/cjs/__test__/client-with-cursor-encryption.test.js.map +1 -1
- package/dist/cjs/__test__/client.test.js +1395 -1497
- package/dist/cjs/__test__/client.test.js.map +1 -1
- package/dist/cjs/__test__/diff.test.d.ts +1 -0
- package/dist/cjs/__test__/diff.test.js +160 -0
- package/dist/cjs/__test__/diff.test.js.map +1 -0
- package/dist/cjs/__test__/rollback.test.d.ts +1 -0
- package/dist/cjs/__test__/rollback.test.js +196 -0
- package/dist/cjs/__test__/rollback.test.js.map +1 -0
- package/dist/cjs/diff.d.ts +3 -0
- package/dist/cjs/diff.js +339 -0
- package/dist/cjs/diff.js.map +1 -0
- package/dist/cjs/sandbox.d.ts +2 -0
- package/dist/cjs/sandbox.js +130 -3
- package/dist/cjs/sandbox.js.map +1 -1
- package/dist/cjs/test-utils/setup.d.ts +1 -1
- package/dist/cjs/test-utils/setup.js +11 -5
- package/dist/cjs/test-utils/setup.js.map +1 -1
- package/dist/esm/__test__/client-with-cursor-encryption.test.js +1241 -1343
- package/dist/esm/__test__/client-with-cursor-encryption.test.js.map +1 -1
- package/dist/esm/__test__/client.test.js +1396 -1498
- package/dist/esm/__test__/client.test.js.map +1 -1
- package/dist/esm/__test__/diff.test.d.ts +1 -0
- package/dist/esm/__test__/diff.test.js +158 -0
- package/dist/esm/__test__/diff.test.js.map +1 -0
- package/dist/esm/__test__/rollback.test.d.ts +1 -0
- package/dist/esm/__test__/rollback.test.js +194 -0
- package/dist/esm/__test__/rollback.test.js.map +1 -0
- package/dist/esm/diff.d.ts +3 -0
- package/dist/esm/diff.js +335 -0
- package/dist/esm/diff.js.map +1 -0
- package/dist/esm/sandbox.d.ts +2 -0
- package/dist/esm/sandbox.js +130 -3
- package/dist/esm/sandbox.js.map +1 -1
- package/dist/esm/test-utils/setup.d.ts +1 -1
- package/dist/esm/test-utils/setup.js +11 -5
- package/dist/esm/test-utils/setup.js.map +1 -1
- package/package.json +1 -1
- package/src/__test__/client-with-cursor-encryption.test.ts +1245 -1347
- package/src/__test__/client.test.ts +1400 -1502
- package/src/__test__/diff.test.ts +165 -0
- package/src/__test__/rollback.test.ts +279 -0
- package/src/diff.ts +443 -0
- package/src/sandbox.ts +173 -3
- package/src/test-utils/setup.ts +9 -5
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { formatSnapshotDiff } from "../diff"
|
|
2
|
+
|
|
3
|
+
describe("formatSnapshotDiff", () => {
|
|
4
|
+
test("renders added items with nested objects and arrays", () => {
|
|
5
|
+
const before = {}
|
|
6
|
+
const after = {
|
|
7
|
+
"PK#user#1__SK#profile": {
|
|
8
|
+
PK: "PK#user#1",
|
|
9
|
+
SK: "SK#profile",
|
|
10
|
+
name: "Ada",
|
|
11
|
+
stats: {
|
|
12
|
+
flags: ["a", "b"],
|
|
13
|
+
logins: 3
|
|
14
|
+
},
|
|
15
|
+
tags: ["alpha", "beta"],
|
|
16
|
+
connections: [
|
|
17
|
+
{
|
|
18
|
+
user: "1"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
user: "2",
|
|
22
|
+
type: "friend"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
expect(formatSnapshotDiff(before, after)).toMatchInlineSnapshot(`
|
|
29
|
+
+ [PK#user#1 / SK#profile]
|
|
30
|
+
+ PK: "PK#user#1"
|
|
31
|
+
+ SK: "SK#profile"
|
|
32
|
+
+ connections:
|
|
33
|
+
+ - user: "1"
|
|
34
|
+
+ - type: "friend"
|
|
35
|
+
+ user: "2"
|
|
36
|
+
+ name: "Ada"
|
|
37
|
+
+ stats:
|
|
38
|
+
+ flags:
|
|
39
|
+
+ - "a"
|
|
40
|
+
+ - "b"
|
|
41
|
+
+ logins: 3
|
|
42
|
+
+ tags:
|
|
43
|
+
+ - "alpha"
|
|
44
|
+
+ - "beta"
|
|
45
|
+
`)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test("renders removed items", () => {
|
|
49
|
+
const before = {
|
|
50
|
+
"PK#post#9__SK#meta": {
|
|
51
|
+
PK: "PK#post#9",
|
|
52
|
+
SK: "SK#meta",
|
|
53
|
+
title: "Removed",
|
|
54
|
+
views: 10
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const after = {}
|
|
58
|
+
|
|
59
|
+
expect(formatSnapshotDiff(before, after)).toMatchInlineSnapshot(`
|
|
60
|
+
- [PK#post#9 / SK#meta]
|
|
61
|
+
- PK: "PK#post#9"
|
|
62
|
+
- SK: "SK#meta"
|
|
63
|
+
- title: "Removed"
|
|
64
|
+
- views: 10
|
|
65
|
+
`)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test("renders updated fields with nested diffs", () => {
|
|
69
|
+
const before = {
|
|
70
|
+
"PK#order#1__SK#summary": {
|
|
71
|
+
PK: "PK#order#1",
|
|
72
|
+
SK: "SK#summary",
|
|
73
|
+
status: "pending",
|
|
74
|
+
count: 1,
|
|
75
|
+
meta: {
|
|
76
|
+
flags: ["a", "b", "c"],
|
|
77
|
+
stats: ["a", "b", "c"],
|
|
78
|
+
config: { enabled: true }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const after = {
|
|
83
|
+
"PK#order#1__SK#summary": {
|
|
84
|
+
PK: "PK#order#1",
|
|
85
|
+
SK: "SK#summary",
|
|
86
|
+
status: "paid",
|
|
87
|
+
count: 2,
|
|
88
|
+
meta: {
|
|
89
|
+
flags: ["a", "c", "d"],
|
|
90
|
+
stats: ["a", "c"],
|
|
91
|
+
config: { enabled: false, mode: "fast" }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
expect(formatSnapshotDiff(before, after)).toMatchInlineSnapshot(`
|
|
97
|
+
[PK#order#1 / SK#summary]
|
|
98
|
+
PK: "PK#order#1"
|
|
99
|
+
SK: "SK#summary"
|
|
100
|
+
- count: 1
|
|
101
|
+
+ count: 2
|
|
102
|
+
meta:
|
|
103
|
+
config:
|
|
104
|
+
- enabled: true
|
|
105
|
+
+ enabled: false
|
|
106
|
+
+ mode: "fast"
|
|
107
|
+
flags:
|
|
108
|
+
- "a"
|
|
109
|
+
- - "b"
|
|
110
|
+
- "c"
|
|
111
|
+
+ - "d"
|
|
112
|
+
stats:
|
|
113
|
+
- "a"
|
|
114
|
+
- - "b"
|
|
115
|
+
- "c"
|
|
116
|
+
- status: "pending"
|
|
117
|
+
+ status: "paid"
|
|
118
|
+
`)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test("skips unchanged items and keeps output compact", () => {
|
|
122
|
+
const before = {
|
|
123
|
+
"PK#steady__SK#1": {
|
|
124
|
+
PK: "PK#steady",
|
|
125
|
+
SK: "SK#1",
|
|
126
|
+
value: "same"
|
|
127
|
+
},
|
|
128
|
+
"PK#beta__SK#1": {
|
|
129
|
+
PK: "PK#beta",
|
|
130
|
+
SK: "SK#1",
|
|
131
|
+
count: 1
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const after = {
|
|
135
|
+
"PK#steady__SK#1": {
|
|
136
|
+
PK: "PK#steady",
|
|
137
|
+
SK: "SK#1",
|
|
138
|
+
value: "same"
|
|
139
|
+
},
|
|
140
|
+
"PK#beta__SK#1": {
|
|
141
|
+
PK: "PK#beta",
|
|
142
|
+
SK: "SK#1",
|
|
143
|
+
count: 2
|
|
144
|
+
},
|
|
145
|
+
"PK#alpha__SK#1": {
|
|
146
|
+
PK: "PK#alpha",
|
|
147
|
+
SK: "SK#1",
|
|
148
|
+
flag: true
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
expect(formatSnapshotDiff(before, after)).toMatchInlineSnapshot(`
|
|
153
|
+
+ [PK#alpha / SK#1]
|
|
154
|
+
+ PK: "PK#alpha"
|
|
155
|
+
+ SK: "SK#1"
|
|
156
|
+
+ flag: true
|
|
157
|
+
|
|
158
|
+
[PK#beta / SK#1]
|
|
159
|
+
PK: "PK#beta"
|
|
160
|
+
SK: "SK#1"
|
|
161
|
+
- count: 1
|
|
162
|
+
+ count: 2
|
|
163
|
+
`)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import * as t from "io-ts"
|
|
2
|
+
import { model } from "@model-ts/core"
|
|
3
|
+
import { Sandbox, createSandbox } from "../sandbox"
|
|
4
|
+
import { Client } from "../client"
|
|
5
|
+
import { getProvider } from "../provider"
|
|
6
|
+
|
|
7
|
+
const client = new Client({ tableName: "table" })
|
|
8
|
+
const provider = getProvider(client)
|
|
9
|
+
|
|
10
|
+
const SIMPLE_CODEC = t.type({
|
|
11
|
+
foo: t.string,
|
|
12
|
+
bar: t.number,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
class Simple extends model("Simple", SIMPLE_CODEC, provider) {
|
|
16
|
+
get PK() {
|
|
17
|
+
return `PK#${this.foo}`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get SK() {
|
|
21
|
+
return `SK#${this.bar}`
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe("rollback", () => {
|
|
26
|
+
let sandbox: Sandbox
|
|
27
|
+
|
|
28
|
+
beforeAll(async () => {
|
|
29
|
+
sandbox = await createSandbox(client)
|
|
30
|
+
await sandbox.seed(
|
|
31
|
+
new Simple({ foo: "seeded1", bar: 1 }),
|
|
32
|
+
new Simple({ foo: "seeded2", bar: 2 })
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
afterAll(async () => {
|
|
37
|
+
await sandbox.destroy()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test("rolls back newly added items", async () => {
|
|
41
|
+
sandbox.startTracking()
|
|
42
|
+
|
|
43
|
+
await new Simple({ foo: "new-item", bar: 99 }).put()
|
|
44
|
+
expect(await sandbox.get("PK#new-item", "SK#99")).not.toBeNull()
|
|
45
|
+
|
|
46
|
+
await sandbox.rollback()
|
|
47
|
+
|
|
48
|
+
expect(await sandbox.get("PK#new-item", "SK#99")).toBeNull()
|
|
49
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
50
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test("rolls back updated items", async () => {
|
|
54
|
+
sandbox.startTracking()
|
|
55
|
+
|
|
56
|
+
await Simple.updateRaw(
|
|
57
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
58
|
+
{ foo: "modified" }
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const modified = await sandbox.get("PK#seeded1", "SK#1")
|
|
62
|
+
expect(modified.foo).toBe("modified")
|
|
63
|
+
|
|
64
|
+
await sandbox.rollback()
|
|
65
|
+
|
|
66
|
+
const restored = await sandbox.get("PK#seeded1", "SK#1")
|
|
67
|
+
expect(restored.foo).toBe("seeded1")
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test("rolls back deleted items", async () => {
|
|
71
|
+
sandbox.startTracking()
|
|
72
|
+
|
|
73
|
+
await Simple.delete({ PK: "PK#seeded1", SK: "SK#1" })
|
|
74
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).toBeNull()
|
|
75
|
+
|
|
76
|
+
await sandbox.rollback()
|
|
77
|
+
|
|
78
|
+
const restored = await sandbox.get("PK#seeded1", "SK#1")
|
|
79
|
+
expect(restored).not.toBeNull()
|
|
80
|
+
expect(restored.foo).toBe("seeded1")
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test("rolls back soft-deleted items", async () => {
|
|
84
|
+
sandbox.startTracking()
|
|
85
|
+
|
|
86
|
+
const item = new Simple({ foo: "seeded1", bar: 1 })
|
|
87
|
+
// @ts-ignore - _docVersion needed for softDelete encoding
|
|
88
|
+
item._docVersion = 0
|
|
89
|
+
await client.softDelete(item)
|
|
90
|
+
|
|
91
|
+
// Original should be gone, deleted version should exist
|
|
92
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).toBeNull()
|
|
93
|
+
expect(
|
|
94
|
+
await sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")
|
|
95
|
+
).not.toBeNull()
|
|
96
|
+
|
|
97
|
+
await sandbox.rollback()
|
|
98
|
+
|
|
99
|
+
// Original should be restored, deleted version should be gone
|
|
100
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
101
|
+
expect(
|
|
102
|
+
await sandbox.get("$$DELETED$$PK#seeded1", "$$DELETED$$SK#1")
|
|
103
|
+
).toBeNull()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test("rolls back mixed operations", async () => {
|
|
107
|
+
sandbox.startTracking()
|
|
108
|
+
|
|
109
|
+
// Add a new item
|
|
110
|
+
await new Simple({ foo: "brand-new", bar: 50 }).put()
|
|
111
|
+
|
|
112
|
+
// Update an existing item
|
|
113
|
+
await Simple.updateRaw(
|
|
114
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
115
|
+
{ foo: "changed" }
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Delete an existing item
|
|
119
|
+
await Simple.delete({ PK: "PK#seeded2", SK: "SK#2" })
|
|
120
|
+
|
|
121
|
+
// Verify all changes took effect
|
|
122
|
+
expect(await sandbox.get("PK#brand-new", "SK#50")).not.toBeNull()
|
|
123
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("changed")
|
|
124
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).toBeNull()
|
|
125
|
+
|
|
126
|
+
await sandbox.rollback()
|
|
127
|
+
|
|
128
|
+
// New item should be gone
|
|
129
|
+
expect(await sandbox.get("PK#brand-new", "SK#50")).toBeNull()
|
|
130
|
+
// Updated item should be restored
|
|
131
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
132
|
+
// Deleted item should be back
|
|
133
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
test("supports multiple tracking/rollback cycles", async () => {
|
|
137
|
+
// Cycle 1
|
|
138
|
+
sandbox.startTracking()
|
|
139
|
+
await new Simple({ foo: "cycle1", bar: 10 }).put()
|
|
140
|
+
await sandbox.rollback()
|
|
141
|
+
expect(await sandbox.get("PK#cycle1", "SK#10")).toBeNull()
|
|
142
|
+
|
|
143
|
+
// Cycle 2
|
|
144
|
+
sandbox.startTracking()
|
|
145
|
+
await new Simple({ foo: "cycle2", bar: 20 }).put()
|
|
146
|
+
await sandbox.rollback()
|
|
147
|
+
expect(await sandbox.get("PK#cycle2", "SK#20")).toBeNull()
|
|
148
|
+
|
|
149
|
+
// Cycle 3 - modify seeded data
|
|
150
|
+
sandbox.startTracking()
|
|
151
|
+
await Simple.updateRaw(
|
|
152
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
153
|
+
{ foo: "cycle3-mod" }
|
|
154
|
+
)
|
|
155
|
+
await sandbox.rollback()
|
|
156
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
157
|
+
|
|
158
|
+
// Seeded data is intact throughout
|
|
159
|
+
expect(await sandbox.get("PK#seeded1", "SK#1")).not.toBeNull()
|
|
160
|
+
expect(await sandbox.get("PK#seeded2", "SK#2")).not.toBeNull()
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test("does not track writes before startTracking", async () => {
|
|
164
|
+
// Write without tracking
|
|
165
|
+
await new Simple({ foo: "untracked", bar: 77 }).put()
|
|
166
|
+
|
|
167
|
+
// Now start tracking and immediately rollback
|
|
168
|
+
sandbox.startTracking()
|
|
169
|
+
await sandbox.rollback()
|
|
170
|
+
|
|
171
|
+
// The untracked write should still be there
|
|
172
|
+
expect(await sandbox.get("PK#untracked", "SK#77")).not.toBeNull()
|
|
173
|
+
|
|
174
|
+
// Clean up manually for subsequent tests
|
|
175
|
+
sandbox.startTracking()
|
|
176
|
+
await Simple.delete({ PK: "PK#untracked", SK: "SK#77" })
|
|
177
|
+
await sandbox.rollback()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
test("tracks the same key modified multiple times", async () => {
|
|
181
|
+
sandbox.startTracking()
|
|
182
|
+
|
|
183
|
+
// Update the same item twice
|
|
184
|
+
await Simple.updateRaw(
|
|
185
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
186
|
+
{ foo: "first-update" }
|
|
187
|
+
)
|
|
188
|
+
await Simple.updateRaw(
|
|
189
|
+
{ PK: "PK#seeded1", SK: "SK#1" },
|
|
190
|
+
{ foo: "second-update" }
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("second-update")
|
|
194
|
+
|
|
195
|
+
await sandbox.rollback()
|
|
196
|
+
|
|
197
|
+
// Should restore to original, not to the intermediate state
|
|
198
|
+
expect((await sandbox.get("PK#seeded1", "SK#1")).foo).toBe("seeded1")
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
describe("rollback with beforeEach/afterEach pattern", () => {
|
|
203
|
+
let sandbox: Sandbox
|
|
204
|
+
|
|
205
|
+
beforeAll(async () => {
|
|
206
|
+
sandbox = await createSandbox(client)
|
|
207
|
+
await sandbox.seed(
|
|
208
|
+
new Simple({ foo: "a", bar: 1 }),
|
|
209
|
+
new Simple({ foo: "b", bar: 2 })
|
|
210
|
+
)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
sandbox.startTracking()
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
afterEach(async () => {
|
|
218
|
+
await sandbox.rollback()
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
afterAll(async () => {
|
|
222
|
+
await sandbox.destroy()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
test("test A: add an item", async () => {
|
|
226
|
+
await new Simple({ foo: "from-test-a", bar: 100 }).put()
|
|
227
|
+
expect(await sandbox.get("PK#from-test-a", "SK#100")).not.toBeNull()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
test("test B: item from test A does not exist", async () => {
|
|
231
|
+
expect(await sandbox.get("PK#from-test-a", "SK#100")).toBeNull()
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
test("test C: modify seeded data", async () => {
|
|
235
|
+
await Simple.updateRaw({ PK: "PK#a", SK: "SK#1" }, { foo: "modified-a" })
|
|
236
|
+
expect((await sandbox.get("PK#a", "SK#1")).foo).toBe("modified-a")
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
test("test D: seeded data is back to original", async () => {
|
|
240
|
+
expect((await sandbox.get("PK#a", "SK#1")).foo).toBe("a")
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
test("test E: delete seeded data", async () => {
|
|
244
|
+
await Simple.delete({ PK: "PK#b", SK: "SK#2" })
|
|
245
|
+
expect(await sandbox.get("PK#b", "SK#2")).toBeNull()
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test("test F: deleted seeded data is back", async () => {
|
|
249
|
+
expect(await sandbox.get("PK#b", "SK#2")).not.toBeNull()
|
|
250
|
+
expect((await sandbox.get("PK#b", "SK#2")).foo).toBe("b")
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
describe("existing sandbox semantics still work", () => {
|
|
255
|
+
let sandbox: Sandbox
|
|
256
|
+
|
|
257
|
+
beforeEach(async () => {
|
|
258
|
+
sandbox = await createSandbox(client)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
afterEach(async () => {
|
|
262
|
+
await sandbox.destroy()
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
test("create and destroy per test still works", async () => {
|
|
266
|
+
await sandbox.seed(new Simple({ foo: "per-test", bar: 1 }))
|
|
267
|
+
|
|
268
|
+
const item = await sandbox.get("PK#per-test", "SK#1")
|
|
269
|
+
expect(item).not.toBeNull()
|
|
270
|
+
expect(item.foo).toBe("per-test")
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
test("snapshot and diff still work", async () => {
|
|
274
|
+
const before = await sandbox.snapshot()
|
|
275
|
+
await new Simple({ foo: "diffed", bar: 1 }).put()
|
|
276
|
+
const diffResult = await sandbox.diff(before)
|
|
277
|
+
expect(diffResult).toContain("PK#diffed")
|
|
278
|
+
})
|
|
279
|
+
})
|