Skip to content

Commit c7b305b

Browse files
authored
Merge branch 'dev' into feat/#358-C
2 parents ad77289 + 727e6af commit c7b305b

File tree

9 files changed

+246
-120
lines changed

9 files changed

+246
-120
lines changed

β€Ž@wabinar/crdt/convergence.test.tsβ€Ž

Lines changed: 0 additions & 83 deletions
This file was deleted.

β€Ž@wabinar/crdt/crdt.test.tsβ€Ž

Lines changed: 0 additions & 34 deletions
This file was deleted.

β€Ž@wabinar/crdt/linked-list.tsβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ export default class LinkedList {
111111

112112
const prevNode = this.findByIndex(index - 1);
113113

114-
if (!prevNode.next) return null;
114+
if (!prevNode.next) throw new Error();
115115

116116
const targetNode = this.getNode(prevNode.next);
117117

118-
if (!targetNode) return null;
118+
if (!targetNode) throw new Error();
119119

120120
this.deleteNode(targetNode.id);
121121
prevNode.next = targetNode.next;
@@ -215,7 +215,7 @@ export default class LinkedList {
215215

216216
spread(): string[] {
217217
let node: Node | null = this.getHeadNode();
218-
let result = [];
218+
let result: string[] = [];
219219

220220
while (node) {
221221
result.push(node.value);
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import CRDT from '../index';
2+
import LinkedList from '../linked-list';
3+
import { convergenceCheck, remoteInsertThroughSocket } from './utils';
4+
5+
let 원희, 주영, λ„ν›ˆ, μ„Έμ˜, remoteSites;
6+
7+
const arrange = () => {
8+
const 원희remotes = [원희.localInsert(-1, 'λ…•'), 원희.localInsert(-1, 'μ•ˆ')];
9+
10+
[주영, λ„ν›ˆ, μ„Έμ˜].forEach((λ‚˜) => {
11+
원희remotes.forEach((op) => remoteInsertThroughSocket(λ‚˜, op));
12+
});
13+
};
14+
15+
describe('Convergence', () => {
16+
beforeEach(() => {
17+
원희 = new CRDT(1, new LinkedList());
18+
주영 = new CRDT(2, new LinkedList());
19+
λ„ν›ˆ = new CRDT(3, new LinkedList());
20+
μ„Έμ˜ = new CRDT(4, new LinkedList());
21+
22+
remoteSites = [원희, 주영, λ„ν›ˆ, μ„Έμ˜];
23+
24+
arrange();
25+
});
26+
27+
it('ν•˜λ‚˜μ˜ siteμ—μ„œ μ‚½μž…', () => {
28+
arrange();
29+
30+
convergenceCheck(remoteSites);
31+
});
32+
33+
it('μ—¬λŸ¬ siteμ—μ„œ 같은 μœ„μΉ˜μ— μ‚½μž…', () => {
34+
const λ„ν›ˆremote = λ„ν›ˆ.localInsert(0, 'μ™­');
35+
const μ„Έμ˜remote = μ„Έμ˜.localInsert(0, '?');
36+
37+
remoteInsertThroughSocket(λ„ν›ˆ, μ„Έμ˜remote);
38+
remoteInsertThroughSocket(μ„Έμ˜, λ„ν›ˆremote);
39+
40+
[원희, 주영].forEach((λ‚˜) => {
41+
remoteInsertThroughSocket(λ‚˜, λ„ν›ˆremote);
42+
remoteInsertThroughSocket(λ‚˜, μ„Έμ˜remote);
43+
});
44+
45+
convergenceCheck(remoteSites);
46+
});
47+
48+
it('μ—¬λŸ¬ siteμ—μ„œ λ‹€λ₯Έ μœ„μΉ˜μ— μ‚½μž…', () => {
49+
const 원희remote = 원희.localInsert(0, 'λ„€');
50+
const 주영remote = 주영.localInsert(1, '!');
51+
52+
remoteInsertThroughSocket(원희, 주영remote);
53+
remoteInsertThroughSocket(주영, 원희remote);
54+
55+
[λ„ν›ˆ, μ„Έμ˜].forEach((λ‚˜) => {
56+
remoteInsertThroughSocket(λ‚˜, 원희remote);
57+
remoteInsertThroughSocket(λ‚˜, 주영remote);
58+
});
59+
60+
convergenceCheck(remoteSites);
61+
});
62+
63+
it('μ—¬λŸ¬ siteμ—μ„œ 같은 μœ„μΉ˜ μ‚­μ œ', () => {
64+
const λ„ν›ˆremote = λ„ν›ˆ.localDelete(0);
65+
const μ„Έμ˜remote = μ„Έμ˜.localDelete(0);
66+
67+
λ„ν›ˆ.remoteDelete(μ„Έμ˜remote);
68+
μ„Έμ˜.remoteDelete(λ„ν›ˆremote);
69+
70+
[원희, 주영].forEach((λ‚˜) => {
71+
λ‚˜.remoteDelete(μ„Έμ˜remote);
72+
λ‚˜.remoteDelete(λ„ν›ˆremote);
73+
});
74+
75+
convergenceCheck(remoteSites);
76+
});
77+
78+
it('μ—¬λŸ¬ siteμ—μ„œ λ‹€λ₯Έ μœ„μΉ˜ μ‚­μ œ', () => {
79+
const 원희remote = 원희.localDelete(0);
80+
const 주영remote = 주영.localDelete(1);
81+
82+
원희.remoteDelete(주영remote);
83+
주영.remoteDelete(원희remote);
84+
85+
[λ„ν›ˆ, μ„Έμ˜].forEach((λ‚˜) => {
86+
λ‚˜.remoteDelete(원희remote);
87+
λ‚˜.remoteDelete(주영remote);
88+
});
89+
90+
convergenceCheck(remoteSites);
91+
});
92+
});
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import CRDT from '../index';
2+
import LinkedList from '../linked-list';
3+
4+
describe('CRDT Local operations', () => {
5+
let λ‚˜;
6+
7+
beforeEach(() => {
8+
const initialStructure = new LinkedList();
9+
λ‚˜ = new CRDT(1, initialStructure);
10+
});
11+
12+
describe('localInsert()', () => {
13+
it('head μœ„μΉ˜ μ‚½μž…μ— μ„±κ³΅ν•œλ‹€.', () => {
14+
// act
15+
λ‚˜.localInsert(-1, 'λ…•');
16+
λ‚˜.localInsert(-1, 'μ•ˆ');
17+
18+
// assert
19+
expect(λ‚˜.read()).toEqual('μ•ˆλ…•');
20+
});
21+
22+
it('tail μœ„μΉ˜ μ‚½μž…μ— μ„±κ³΅ν•œλ‹€.', () => {
23+
// act
24+
λ‚˜.localInsert(-1, 'μ•ˆ');
25+
λ‚˜.localInsert(0, 'λ…•');
26+
27+
// assert
28+
expect(λ‚˜.read()).toEqual('μ•ˆλ…•');
29+
});
30+
31+
it('μ—†λŠ” μœ„μΉ˜μ— μ‚½μž… μ‹œλ„ μ‹œ μ—λŸ¬λ₯Ό λ˜μ§„λ‹€.', () => {
32+
// arrange
33+
λ‚˜.localInsert(-1, 'μ•ˆ');
34+
35+
// act & assert
36+
expect(() => λ‚˜.localInsert(1, 'λ…•')).toThrow();
37+
});
38+
});
39+
40+
describe('localDelete()', () => {
41+
it('tail μœ„μΉ˜ μ‚­μ œμ— μ„±κ³΅ν•œλ‹€.', () => {
42+
// arrange
43+
λ‚˜.localInsert(-1, 'μ•ˆ');
44+
λ‚˜.localInsert(0, 'λ…•');
45+
46+
// act
47+
λ‚˜.localDelete(1);
48+
49+
// assert
50+
expect(λ‚˜.read()).toEqual('μ•ˆ');
51+
});
52+
53+
it('μ—†λŠ” μœ„μΉ˜μ— μ‚­μ œ μ‹œλ„ μ‹œ μ—λŸ¬λ₯Ό λ˜μ§„λ‹€.', () => {
54+
// arrange
55+
λ‚˜.localInsert(-1, 'μ•ˆ');
56+
57+
// act & assert
58+
expect(() => λ‚˜.localDelete(1)).toThrow();
59+
});
60+
});
61+
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import CRDT from '../index';
2+
import LinkedList from '../linked-list';
3+
import { remoteInsertThroughSocket } from './utils';
4+
5+
describe('Exceptions', () => {
6+
let λ„ν›ˆ, ν˜Έλ‘”, remoteSites;
7+
8+
beforeEach(() => {
9+
λ„ν›ˆ = new CRDT(1, new LinkedList());
10+
ν˜Έλ‘” = new CRDT(2, new LinkedList());
11+
12+
remoteSites = [λ„ν›ˆ, ν˜Έλ‘”];
13+
14+
const λ„ν›ˆremotes = [
15+
λ„ν›ˆ.localInsert(-1, 'λ…•'),
16+
λ„ν›ˆ.localInsert(-1, 'μ•ˆ'),
17+
];
18+
λ„ν›ˆremotes.forEach((op) => remoteInsertThroughSocket(ν˜Έλ‘”, op));
19+
});
20+
21+
it('μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μΈλ±μŠ€μ— localInsert', () => {
22+
expect(() => λ„ν›ˆ.localInsert(100, '.')).toThrow();
23+
});
24+
25+
it('μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ…Έλ“œ 뒀에 remoteInsert', () => {
26+
const λ„ν›ˆremotes = [
27+
λ„ν›ˆ.localInsert(1, '.'),
28+
λ„ν›ˆ.localInsert(2, '.'),
29+
λ„ν›ˆ.localInsert(3, '.'),
30+
];
31+
32+
// μ—°μ†λœ remote operation μˆœμ„œκ°€ μ„žμ΄λŠ” μΌ€μ΄μŠ€
33+
expect(() => ν˜Έλ‘”.remoteInsert(λ„ν›ˆremotes[1])).toThrow();
34+
});
35+
36+
it('localμ—μ„œ μ‚­μ œλœ λ…Έλ“œ 뒀에 μ‚½μž…', () => {
37+
const λ„ν›ˆremote = λ„ν›ˆ.localInsert(0, '!');
38+
const ν˜Έλ‘”remote = ν˜Έλ‘”.localDelete(0);
39+
40+
expect(() => ν˜Έλ‘”.remoteInsert(λ„ν›ˆremote)).toThrow();
41+
});
42+
});

β€Ž@wabinar/crdt/test/utils.tsβ€Ž

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import CRDT from '../index';
2+
import { RemoteInsertOperation } from '../linked-list';
3+
import { Node } from '../node';
4+
5+
/**
6+
* λͺ¨λ“  remote site λ¬Έμžμ—΄μ΄ μΌμΉ˜ν•˜λŠ”μ§€ 확인
7+
*/
8+
export const convergenceCheck = (remoteSites) => {
9+
const convergenceSet = remoteSites.reduce((prev, cur, index) => {
10+
if (index < remoteSites.length - 1) {
11+
prev.push([cur, remoteSites[index + 1]]);
12+
}
13+
14+
return prev;
15+
}, []);
16+
17+
convergenceSet.forEach(([first, second]) => {
18+
expect(first.read()).toEqual(second.read());
19+
});
20+
};
21+
22+
/**
23+
* λ°”λ‘œ μ „λ‹¬ν•˜λ©΄ 같은 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€κ²Œ λ˜μ–΄ remote operation μ˜λ―Έκ°€ 사라짐
24+
*/
25+
const deepCopyRemoteInsertion = (op: RemoteInsertOperation) => {
26+
const { node } = op;
27+
28+
const copy = { ...node };
29+
Object.setPrototypeOf(copy, Node.prototype);
30+
31+
return { node: copy as Node };
32+
};
33+
34+
export const remoteInsertThroughSocket = (
35+
crdt: CRDT,
36+
op: RemoteInsertOperation,
37+
) => {
38+
const copy = deepCopyRemoteInsertion(op);
39+
crdt.remoteInsert(copy);
40+
};

β€Ž@wabinar/crdt/tsconfig.jsonβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"esModuleInterop": true
4+
}
5+
}

β€Žpackage.jsonβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
"server/**/*.ts": [
2626
"prettier --write",
2727
"eslint --config ./server/.eslintrc --fix"
28+
],
29+
"@wabinar/**/*.ts": [
30+
"prettier --write"
2831
]
2932
},
3033
"workspaces": [

0 commit comments

Comments
Β (0)