Skip to content

Commit

Permalink
add doc.get_last_local_change
Browse files Browse the repository at this point in the history
  • Loading branch information
nornagon committed Mar 21, 2024
1 parent 9f2d0ac commit 40e9d6c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
11 changes: 11 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,17 @@ impl Document {
Ok(inner.get_heads())
}

fn get_last_local_change(&self) -> PyResult<Option<PyChange>> {
let inner = self
.inner
.read()
.map_err(|e| PyException::new_err(e.to_string()))?;
Ok(inner
.doc
.get_last_local_change()
.map(|c| PyChange(c.to_owned())))
}

fn object_type(&self, obj_id: PyObjId) -> PyResult<PyObjType> {
let inner = self
.inner
Expand Down
1 change: 1 addition & 0 deletions src/automerge/_automerge.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Document:
def receive_sync_message(self, state: SyncState, msg: Message) -> None: ...

def get_heads(self) -> list[bytes]: ...
def get_last_local_change(self) -> Optional[Change]: ...
def object_type(self, obj_id: bytes) -> ObjType: ...
def get_changes(self, have_deps: list[bytes]) -> list[Change]: ...
def get(self, obj_id: bytes, prop: str | int, heads: Optional[list[bytes]] = None) -> Optional[tuple[Value, bytes]]: ...
Expand Down
28 changes: 28 additions & 0 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,31 @@ def test_diff() -> None:
patch = doc.diff([], doc.get_heads())
assert len(patch) == 4

def test_text_heads() -> None:
doc1 = Document(actor_id=b'A')

with doc1.transaction() as tx:
text_id = tx.put_object(ROOT, "text", ObjType.Text)
tx.insert(text_id, 0, ScalarType.Str, "h")

doc2 = doc1.fork()
doc2.set_actor(b'B')

with doc1.transaction() as tx:
tx.insert(text_id, 1, ScalarType.Str, "i")

with doc2.transaction() as tx:
tx.insert(text_id, 1, ScalarType.Str, "o")

a_change = doc1.get_last_local_change()
assert a_change is not None
b_change = doc2.get_last_local_change()
assert b_change is not None

doc1.merge(doc2)
heads = doc1.get_heads()
assert len(heads) == 2

assert doc1.text(text_id, [a_change.hash]) == 'hi'
assert doc1.text(text_id, [b_change.hash]) == 'ho'
assert doc1.text(text_id, [a_change.hash, b_change.hash]) == 'hoi'
10 changes: 6 additions & 4 deletions tests/test_changes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import datetime
from typing import List
from automerge.core import Document, ROOT, ScalarType, ObjType, extract
from typing import List, Optional, Tuple
from automerge.core import Document, ROOT, ScalarType, ObjType

def test_get_changes() -> None:
doc = Document()
Expand Down Expand Up @@ -68,6 +68,8 @@ def test_multi_author_changes() -> None:
docB.merge(docA)
docA.merge(docB)

assert len(docA.get_heads()) == 2

# docA and docB are the same now, so pick one arbitrarily to read changes
# out of for history linearization
doc = docA
Expand All @@ -76,8 +78,8 @@ def test_multi_author_changes() -> None:
assert changes[0].actor_id == b'A'
assert changes[1].actor_id == b'B'

last_actor: bytes | None = None
snapshots: List[tuple[str, bytes | None]] = []
last_actor: Optional[bytes] = None
snapshots: List[Tuple[str, Optional[bytes]]] = []
seen_heads: List[bytes] = []
# Go through each of the changes, saving when the author changes.
for change in changes:
Expand Down

0 comments on commit 40e9d6c

Please sign in to comment.