Skip to content

Commit

Permalink
Drop YTest (#14)
Browse files Browse the repository at this point in the history
* Drop YTest

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
davidbrochart and pre-commit-ci[bot] authored Feb 12, 2024
1 parent 734f4d2 commit 1671747
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 85 deletions.
78 changes: 36 additions & 42 deletions tests/test_pycrdt_yjs.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,69 @@
from __future__ import annotations

from functools import partial

import pytest
from anyio import Event, create_task_group, move_on_after, sleep
from anyio import Event, fail_after
from pycrdt import Array, Doc, Map
from websockets import connect

from pycrdt_websocket import WebsocketProvider


class YTest:
def __init__(self, ydoc: Doc, timeout: float = 1.0):
self.ydoc = ydoc
class Change:
def __init__(self, event, timeout, ydata, sid, key):
self.event = event
self.timeout = timeout
self.ydoc["_test"] = self.ytest = Map()
self.clock = -1.0
self.ydata = ydata
self.sid = sid
self.key = key

def run_clock(self):
self.clock = max(self.clock, 0.0)
self.ytest["clock"] = self.clock
async def wait(self):
with fail_after(self.timeout):
await self.event.wait()
self.ydata.unobserve(self.sid)
if self.key is None:
return
return self.ydata[self.key]

async def clock_run(self):
change = Event()

def callback(event):
if "clock" in event.keys:
clk = event.keys["clock"]["newValue"]
if clk > self.clock:
self.clock = clk + 1.0
change.set()
def callback(change_event, key, event):
if key is None or key in event.keys:
change_event.set()

subscription_id = self.ytest.observe(callback)
async with create_task_group():
with move_on_after(self.timeout):
await change.wait()

self.ytest.unobserve(subscription_id)
def watch(ydata, key: str | None = None, timeout: float = 1.0):
change_event = Event()
sid = ydata.observe(partial(callback, change_event, key))
return Change(change_event, timeout, ydata, sid, key)


@pytest.mark.anyio
@pytest.mark.parametrize("yjs_client", "0", indirect=True)
async def test_pycrdt_yjs_0(yws_server, yjs_client):
ydoc = Doc()
ytest = YTest(ydoc)
async with connect("ws://127.0.0.1:1234/my-roomname") as websocket, WebsocketProvider(
ydoc, websocket
):
ydoc["map"] = ymap = Map()
# set a value in "in"
for v_in in range(10):
ymap["in"] = float(v_in)
ytest.run_clock()
await ytest.clock_run()
v_out = ymap["out"]
v_out = await watch(ymap, "out").wait()
assert v_out == v_in + 1.0


@pytest.mark.anyio
@pytest.mark.parametrize("yjs_client", "1", indirect=True)
async def test_pycrdt_yjs_1(yws_server, yjs_client):
# wait for the JS client to connect
tt, dt = 0, 0.1
while True:
await sleep(dt)
if "/my-roomname" in yws_server.rooms:
break
tt += dt
if tt >= 1:
raise RuntimeError("Timeout waiting for client to connect")
ydoc = yws_server.rooms["/my-roomname"].ydoc
ytest = YTest(ydoc)
ytest.run_clock()
await ytest.clock_run()
ydoc = Doc()
ydoc["cells"] = ycells = Array()
ydoc["state"] = ystate = Map()
assert ycells.to_py() == [{"metadata": {"foo": "bar"}, "source": "1 + 2"}]
assert ystate.to_py() == {"state": {"dirty": False}}
ycells_change = watch(ycells)
ystate_change = watch(ystate)
async with connect("ws://127.0.0.1:1234/my-roomname") as websocket, WebsocketProvider(
ydoc, websocket
):
await ycells_change.wait()
await ystate_change.wait()
assert ycells.to_py() == [{"metadata": {"foo": "bar"}, "source": "1 + 2"}]
assert ystate.to_py() == {"state": {"dirty": False}}
34 changes: 13 additions & 21 deletions tests/yjs_client_0.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
const Y = require('yjs')
const WebsocketProvider = require('y-websocket').WebsocketProvider
const ws = require('ws')

const ydoc = new Y.Doc()
const ytest = ydoc.getMap('_test')
const ymap = ydoc.getMap('map')
const ws = require('ws')

function increment(resolve) {
ymap.set('out', ymap.get('in') + 1);
resolve();
}

ymap.observe(event => {
if (event.transaction.local || !event.changes.keys.has('in')) {
return
}
new Promise(increment);
})

const wsProvider = new WebsocketProvider(
'ws://127.0.0.1:1234', 'my-roomname',
ydoc,
{ WebSocketPolyfill: ws }
)

wsProvider.on('status', event => {
console.log(event.status)
})

var clock = -1

ytest.observe(event => {
event.changes.keys.forEach((change, key) => {
if (key === 'clock') {
const clk = ytest.get('clock')
if (clk > clock) {
ymap.set('out', ymap.get('in') + 1)
clock = clk + 1
ytest.set('clock', clock)
}
}
})
})
30 changes: 8 additions & 22 deletions tests/yjs_client_1.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
const Y = require('yjs')
const WebsocketProvider = require('y-websocket').WebsocketProvider
const ws = require('ws')

const ydoc = new Y.Doc()
const ytest = ydoc.getMap('_test')
const ycells = ydoc.getArray("cells")
const ystate = ydoc.getMap("state")
const ws = require('ws')

const wsProvider = new WebsocketProvider(
'ws://127.0.0.1:1234', 'my-roomname',
ydoc,
{ WebSocketPolyfill: ws }
)

wsProvider.on('status', event => {
console.log(event.status)
})

var clock = -1
wsProvider.on('sync', () => {
const ycells = ydoc.getArray('cells')
const ystate = ydoc.getMap('state')

ytest.observe(event => {
event.changes.keys.forEach((change, key) => {
if (key === 'clock') {
const clk = ytest.get('clock')
if (clk > clock) {
const cells = [new Y.Map([['source', new Y.Text('1 + 2')], ['metadata', {'foo': 'bar'}]])]
ycells.push(cells)
ystate.set('state', {'dirty': false})
clock = clk + 1
ytest.set('clock', clock)
}
}
})
const cells = [new Y.Map([['source', new Y.Text('1 + 2')], ['metadata', {'foo': 'bar'}]])]
const state = {'dirty': false}
ycells.push(cells)
ystate.set('state', state)
})

0 comments on commit 1671747

Please sign in to comment.