Skip to content
File

Blob: src/workerd/api/tests/sync-kv-test.js

javascript122 lines
1// Copyright (c) 2025 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4import { DurableObject } from 'cloudflare:workers';
5import assert from 'node:assert';
6 
7export class MyActor extends DurableObject {
8 run() {
9 let kv = this.ctx.storage.kv;
10 
11 assert.strictEqual(kv.get('foo'), undefined);
12 kv.put('foo', 123);
13 assert.strictEqual(kv.get('foo'), 123);
14 
15 assert.strictEqual(kv.get('bar'), undefined);
16 kv.put('bar', 'abc');
17 assert.strictEqual(kv.get('bar'), 'abc');
18 
19 // Iterates in alphabetical order.
20 assert.deepEqual(
21 [...kv.list()],
22 [
23 ['bar', 'abc'],
24 ['foo', 123],
25 ]
26 );
27 
28 assert.deepEqual(
29 [...kv.list({ reverse: true })],
30 [
31 ['foo', 123],
32 ['bar', 'abc'],
33 ]
34 );
35 
36 // A new call to kv.list() invalidates any previous iterator.
37 {
38 let cursor1 = kv.list();
39 let cursor2 = kv.list();
40 
41 assert.throws(() => [...cursor1], {
42 name: 'Error',
43 message:
44 'kv.list() iterator was invalidated because a new call to kv.list() was started. ' +
45 'Only one kv.list() iterator can exist at a time.',
46 });
47 
48 assert.deepEqual(
49 [...cursor2],
50 [
51 ['bar', 'abc'],
52 ['foo', 123],
53 ]
54 );
55 }
56 
57 kv.put('baz', false);
58 
59 // Try a prefix.
60 assert.deepEqual(
61 [...kv.list({ prefix: 'ba' })],
62 [
63 ['bar', 'abc'],
64 ['baz', false],
65 ]
66 );
67 
68 // Try a limit.
69 assert.deepEqual([...kv.list({ limit: 1 })], [['bar', 'abc']]);
70 
71 // Try a reverse limit.
72 assert.deepEqual([...kv.list({ limit: 1, reverse: true })], [['foo', 123]]);
73 
74 // Try a range.
75 assert.deepEqual(
76 [...kv.list({ start: 'b', end: 'c' })],
77 [
78 ['bar', 'abc'],
79 ['baz', false],
80 ]
81 );
82 
83 // End is exclusive.
84 assert.deepEqual(
85 [...kv.list({ start: 'b', end: 'baz' })],
86 [['bar', 'abc']]
87 );
88 
89 // Start is inclusive.
90 assert.deepEqual(
91 [...kv.list({ start: 'bar', end: 'c' })],
92 [
93 ['bar', 'abc'],
94 ['baz', false],
95 ]
96 );
97 
98 // Except when it's not.
99 assert.deepEqual(
100 [...kv.list({ startAfter: 'bar', end: 'c' })],
101 [['baz', false]]
102 );
103 
104 // Test delete.
105 assert.strictEqual(kv.delete('qux'), false);
106 assert.strictEqual(kv.delete('bar'), true);
107 assert.deepEqual(
108 [...kv.list()],
109 [
110 ['baz', false],
111 ['foo', 123],
112 ]
113 );
114 }
115}
116 
117export let testAutoRollBackOnCriticalError = {
118 async test(ctrl, env, ctx) {
119 await ctx.exports.MyActor.getByName('foo').run();
120 },
121};