Skip to content

Commit

Permalink
InlineWriteTracker (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Mar 26, 2024
2 parents e6c5905 + 4d6d4c4 commit ba8329a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 15 deletions.
18 changes: 5 additions & 13 deletions python/selfie-lib/selfie_lib/CommentTracker.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
from typing import Dict, Iterable, Tuple
from typing import Dict, Iterable, Tuple, Sequence, TypeVar, Callable
from abc import ABC, abstractmethod
from enum import Enum, auto
import threading
from selfie_lib.TypedPath import TypedPath
from selfie_lib.Slice import Slice


# Placeholder implementations for CallStack, SnapshotFileLayout, and FS
class CallStack:
pass


class SnapshotFileLayout:
def sourcePathForCall(self, location) -> "TypedPath":
# Placeholder return or raise NotImplementedError
raise NotImplementedError("sourcePathForCall is not implemented")
from selfie_lib.Slice import Slice
from selfie_lib.TypedPath import TypedPath
from selfie_lib.WriteTracker import CallStack, SnapshotFileLayout


class WritableComment(Enum):
Expand Down
71 changes: 69 additions & 2 deletions python/selfie-lib/selfie_lib/WriteTracker.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
from typing import List, Optional, Generic, TypeVar, Dict
from selfie_lib.CommentTracker import SnapshotFileLayout
from typing import List, Optional, Generic, TypeVar, Dict, cast, Callable, Sequence
from abc import ABC, abstractmethod
import inspect, threading
from functools import total_ordering

from selfie_lib.SourceFile import SourceFile
from selfie_lib.Literals import LiteralValue
from selfie_lib.TypedPath import TypedPath


T = TypeVar("T")
U = TypeVar("U")


class FS(ABC):
@abstractmethod
def file_walk(self, typed_path, walk: Callable[[Sequence["TypedPath"]], T]) -> T:
pass

def file_read(self, typed_path) -> str:
return self.file_read_binary(typed_path).decode()

def file_write(self, typed_path, content: str):
self.file_write_binary(typed_path, content.encode())

@abstractmethod
def file_read_binary(self, typed_path) -> bytes:
pass

@abstractmethod
def file_write_binary(self, typed_path, content: bytes):
pass

@abstractmethod
def assert_failed(self, message: str, expected=None, actual=None) -> Exception:
pass


class SnapshotFileLayout:
def __init__(self, fs: FS):
self.fs = fs

def sourcePathForCall(self, location) -> "TypedPath":
raise NotImplementedError("sourcePathForCall is not implemented")


@total_ordering
class CallLocation:
def __init__(self, file_name: Optional[str], line: int):
Expand Down Expand Up @@ -132,3 +168,34 @@ def recordInternal(
class DiskWriteTracker(WriteTracker[T, U]):
def record(self, key: T, snapshot: U, call: CallStack, layout: SnapshotFileLayout):
super().recordInternal(key, snapshot, call, layout)


class InlineWriteTracker(WriteTracker[CallLocation, LiteralValue]):
def record(
self,
key: CallLocation,
snapshot: LiteralValue,
call: CallStack,
layout: SnapshotFileLayout,
):
super().recordInternal(key, snapshot, call, layout)

file = layout.sourcePathForCall(key)
if snapshot.expected is not None:
content = SourceFile(file.name, layout.fs.file_read(file))
try:
snapshot = cast(LiteralValue, snapshot)
parsed_value = content.parse_to_be_like(key.line).parse_literal(
snapshot.format
)
except Exception as e:
raise AssertionError(
f"Error while parsing the literal at {key.ide_link(layout)}. Please report this error at https://github.com/diffplug/selfie",
e,
)
if parsed_value != snapshot.expected:
raise layout.fs.assert_failed(
f"Selfie cannot modify the literal at {key.ide_link(layout)} because Selfie has a parsing bug. Please report this error at https://github.com/diffplug/selfie",
snapshot.expected,
parsed_value,
)

0 comments on commit ba8329a

Please sign in to comment.