-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathGraph.subscribe.spec.ts
More file actions
124 lines (107 loc) · 4.08 KB
/
Graph.subscribe.spec.ts
File metadata and controls
124 lines (107 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { expect } from '@jest/globals';
import { scenario } from '@testduet/given-when-then';
import { fn } from 'jest-mock';
import { assert, map, string, unknown } from 'valibot';
import Graph, { type GraphState } from './Graph';
import './schemas/private/expectExtendValibot';
import './schemas/private/expectIsFrozen';
scenario('Graph.subscribe()', bdd => {
bdd
.given('a Graph object and a subscriber', () => {
const graph = new Graph(() => () => request => request);
const subscriber = fn();
graph.subscribe(subscriber);
return { graph, subscriber };
})
.when('act().getState() is called', ({ graph }) => {
let returnValue;
graph.act(({ getState }) => {
returnValue = getState();
});
return returnValue;
})
.then('context.state should be of type Map', (_, state) => expect(state).toBeInstanceOf(Map))
.and('context.state should be frozen', (_, state) => expect(Object.isFrozen(state)).toBe(true))
.and('subscriber should not have been called', ({ subscriber }) =>
// Because there are no changes.
expect(subscriber).not.toHaveBeenCalled()
);
bdd
.given('a Graph object and a subscriber', () => {
const graph = new Graph(() => () => request => request);
const subscriber = fn();
const unsubscribe = graph.subscribe(subscriber);
return { graph, subscriber, unsubscribe };
})
.when('act().upsert() is called', ({ graph }) => {
let returnValue: GraphState | undefined;
graph.act(({ getState, upsert }) => {
upsert({ '@id': '_:b1' });
returnValue = getState();
});
assert(map(string(), unknown()), returnValue);
return returnValue;
})
.then('subscriber should have been called once', ({ subscriber }) => expect(subscriber).toHaveBeenCalledTimes(1))
.and('subscriber should have been called with changed node identifiers', ({ subscriber }) =>
expect(subscriber).toHaveBeenNthCalledWith(1, { upsertedNodeIdentifiers: new Set(['_:b1']) })
)
.and('subscriber should have been called with frozen', ({ subscriber }) => {
expect(subscriber).toHaveBeenNthCalledWith(1, expect.isFrozen());
expect(subscriber).toHaveBeenNthCalledWith(1, { upsertedNodeIdentifiers: expect.isFrozen() });
})
.and('getState() should have the newly added node', ({ graph }) =>
expect(graph.getState()).toEqual(
new Map(
Object.entries({
'_:b1': {
'@id': '_:b1'
}
})
)
)
)
.and('getState() should be frozen', ({ graph }) => expect(graph.getState()).toEqual(expect.isFrozen()))
.and('getState() alled during act() should not do dirty read', (_, dirtyGraph) => {
expect(dirtyGraph).toEqual(new Map());
expect(dirtyGraph).toEqual(expect.isFrozen());
})
.when('unsubscribe() is called', ({ unsubscribe }) => unsubscribe())
.then('act().snapshot() should not call subscriber', ({ graph, subscriber }) => {
expect(subscriber).toHaveBeenCalledTimes(1); // Subscriber have been called once previously, so it should kept at 1.
graph.act(graph => graph.upsert({ '@id': '_:b1' }));
expect(subscriber).toHaveBeenCalledTimes(1);
});
bdd
.given('a Graph object and a subscriber which will call act() when triggered', () => {
const graph = new Graph(() => () => request => request);
const subscriber = fn(() => {
// Should throw.
graph.act(({ upsert }) => {
upsert({ '@id': '_:b2' });
});
});
graph.subscribe(subscriber);
return { graph, subscriber };
})
.when('act().upsert() is called', ({ graph }) => {
try {
graph.act(({ upsert }) => {
upsert({ '@id': '_:b1' });
});
} catch (error) {
return error;
}
return undefined;
})
.then('getState() should return both nodes', ({ graph }) =>
expect(graph.getState()).toEqual(
new Map(
Object.entries({
'_:b1': { '@id': '_:b1' },
'_:b2': { '@id': '_:b2' }
})
)
)
);
});