Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
changed testing to reflect kotlin code and added a way to access the …
Browse files Browse the repository at this point in the history
…private variables
  • Loading branch information
SDelgado-21 committed Mar 14, 2024
1 parent 3ba9c3f commit 4e73dd7
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 174 deletions.
56 changes: 31 additions & 25 deletions python/selfie-lib/selfie_lib/SourceFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, filename: str, content: str) -> None:
self.__content_slice: Slice = Slice(content.replace("\r\n", "\n"))
self.__language: Language = Language.from_filename(filename)
self.__escape_leading_whitespace = EscapeLeadingWhitespace.appropriate_for(
self.content_slice.__str__()
self.__content_slice.__str__()
)

@property
Expand All @@ -38,6 +38,12 @@ def __init__(
self.__language = language
self.__escape_leading_whitespace = escape_leading_whitespace

def _get_function_call_plus_arg(self):
return self.__function_call_plus_arg

def _get_arg(self):
return self.__arg

def set_literal_and_get_newline_delta(self, literal_value: LiteralValue) -> int:
encoded = literal_value.format.encode(
literal_value.actual, self.__language, self.__escape_leading_whitespace
Expand All @@ -57,7 +63,7 @@ def set_literal_and_get_newline_delta(self, literal_value: LiteralValue) -> int:
)
existing_newlines = self.__function_call_plus_arg.count("\n")
new_newlines = encoded.count("\n")
self.content_slice = self.__function_call_plus_arg.replaceSelfWith(
self.__content_slice = self.__function_call_plus_arg.replaceSelfWith(
f"{self.__dot_fun_open_paren}{encoded})"
)
return new_newlines - existing_newlines
Expand All @@ -66,7 +72,7 @@ def parse_literal(self, literal_format: LiteralFormat) -> Any:
return literal_format.parse(self.__arg.__str__(), self.__language)

def find_on_line(self, to_find: str, line_one_indexed: int) -> Slice:
line_content = self.content_slice.unixLine(line_one_indexed)
line_content = self.__content_slice.unixLine(line_one_indexed)
idx = line_content.indexOf(to_find)
if idx == -1:
raise AssertionError(
Expand All @@ -80,12 +86,12 @@ def find_on_line(self, to_find: str, line_one_indexed: int) -> Slice:
def replace_on_line(self, line_one_indexed: int, find: str, replace: str) -> None:
assert "\n" not in find
assert "\n" not in replace
line_content = self.content_slice.unixLine(line_one_indexed).__str__()
line_content = self.__content_slice.unixLine(line_one_indexed).__str__()
new_content = line_content.replace(find, replace)
self.content_slice = Slice(self.content_slice.replaceSelfWith(new_content))
self.__content_slice = Slice(self.__content_slice.replaceSelfWith(new_content))

def parse_to_be_like(self, line_one_indexed: int) -> ToBeLiteral:
line_content = self.content_slice.unixLine(line_one_indexed)
line_content = self.__content_slice.unixLine(line_one_indexed)
dot_fun_open_paren = None

for to_be_like in TO_BE_LIKES:
Expand All @@ -102,24 +108,24 @@ def parse_to_be_like(self, line_one_indexed: int) -> ToBeLiteral:
dot_function_call = dot_function_call_in_place + line_content.startIndex
arg_start = dot_function_call + len(dot_fun_open_paren)

if self.content_slice.__len__() == arg_start:
if self.__content_slice.__len__() == arg_start:
raise AssertionError(
f"Appears to be an unclosed function call `{dot_fun_open_paren}` "
f"on line {line_one_indexed}"
)
while self.content_slice[arg_start].isspace():
while self.__content_slice[arg_start].isspace():
arg_start += 1
if self.content_slice.__len__() == arg_start:
if self.__content_slice.__len__() == arg_start:
raise AssertionError(
f"Appears to be an unclosed function call `{dot_fun_open_paren}` "
f"on line {line_one_indexed}"
)

end_arg = -1
end_paren = 0
if self.content_slice[arg_start] == '"':
if self.content_slice[arg_start].startswith(self.TRIPLE_QUOTE):
end_arg = self.content_slice.indexOf(
if self.__content_slice[arg_start] == '"':
if self.__content_slice[arg_start].startswith(self.TRIPLE_QUOTE):
end_arg = self.__content_slice.indexOf(
self.TRIPLE_QUOTE, arg_start + len(self.TRIPLE_QUOTE)
)
if end_arg == -1:
Expand All @@ -133,11 +139,11 @@ def parse_to_be_like(self, line_one_indexed: int) -> ToBeLiteral:
else:
end_arg = arg_start + 1
while (
self.content_slice[end_arg] != '"'
or self.content_slice[end_arg - 1] == "\\"
self.__content_slice[end_arg] != '"'
or self.__content_slice[end_arg - 1] == "\\"
):
end_arg += 1
if end_arg == self.content_slice.__len__():
if end_arg == self.__content_slice.__len__():
raise AssertionError(
f'Appears to be an unclosed string literal `"` '
f"on line {line_one_indexed}"
Expand All @@ -146,34 +152,34 @@ def parse_to_be_like(self, line_one_indexed: int) -> ToBeLiteral:
end_paren = end_arg
else:
end_arg = arg_start
while not self.content_slice[end_arg].isspace():
if self.content_slice[end_arg] == ")":
while not self.__content_slice[end_arg].isspace():
if self.__content_slice[end_arg] == ")":
break
end_arg += 1
if end_arg == self.content_slice.__len__():
if end_arg == self.__content_slice.__len__():
raise AssertionError(
f"Appears to be an unclosed numeric literal "
f"on line {line_one_indexed}"
)
end_paren = end_arg
while self.content_slice[end_paren] != ")":
if not self.content_slice[end_paren].isspace():
while self.__content_slice[end_paren] != ")":
if not self.__content_slice[end_paren].isspace():
raise AssertionError(
f"Non-primitive literal in `{dot_fun_open_paren}` starting at "
f"line {line_one_indexed}: error for character "
f"`{self.content_slice[end_paren]}` on line "
f"{self.content_slice.baseLineAtOffset(end_paren)}"
f"`{self.__content_slice[end_paren]}` on line "
f"{self.__content_slice.baseLineAtOffset(end_paren)}"
)
end_paren += 1
if end_paren == self.content_slice.__len__():
if end_paren == self.__content_slice.__len__():
raise AssertionError(
f"Appears to be an unclosed function call `{dot_fun_open_paren}` "
f"starting at line {line_one_indexed}"
)
return self.ToBeLiteral(
dot_fun_open_paren.replace("_TODO", ""),
self.content_slice.subSequence(dot_function_call, end_paren + 1),
self.content_slice.subSequence(arg_start, end_arg),
self.__content_slice.subSequence(dot_function_call, end_paren + 1),
self.__content_slice.subSequence(arg_start, end_arg),
self.__language,
self.__escape_leading_whitespace,
)
Expand Down
213 changes: 64 additions & 149 deletions python/selfie-lib/tests/SourceFile_test.py
Original file line number Diff line number Diff line change
@@ -1,175 +1,90 @@
from selfie_lib import SourceFile


def test_todo():
source_file = SourceFile("UnderTest.py", ".toBe_TODO()")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe_TODO()"
assert str(source_file.parse_to_be_like(1).arg) == ""

source_file = SourceFile("UnderTest.py", " .toBe_TODO() ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe_TODO()"
assert str(source_file.parse_to_be_like(1).arg) == ""

source_file = SourceFile("UnderTest.py", " .toBe_TODO( ) ")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe_TODO( )"
)
assert str(source_file.parse_to_be_like(1).arg) == ""

source_file = SourceFile("UnderTest.py", " .toBe_TODO( \n ) ")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg)
== ".toBe_TODO( \n )"
)
assert str(source_file.parse_to_be_like(1).arg) == ""


def test_numeric():
source_file = SourceFile("UnderTest.py", ".toBe(7)")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(7)"
assert str(source_file.parse_to_be_like(1).arg) == "7"

source_file = SourceFile("UnderTest.py", " .toBe(7)")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(7)"
assert str(source_file.parse_to_be_like(1).arg) == "7"

source_file = SourceFile("UnderTest.py", ".toBe(7) ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(7)"
assert str(source_file.parse_to_be_like(1).arg) == "7"
def python_test(source_raw, function_call_plus_arg_raw, arg_raw=""):
source = source_raw.replace("'", '"')
function_call_plus_arg = function_call_plus_arg_raw.replace("'", '"')
arg = arg_raw.replace("'", '"')
parsed = SourceFile("UnderTest.py", source)
to_be_literal = parsed.parse_to_be_like(1)
assert to_be_literal._get_function_call_plus_arg() == function_call_plus_arg
assert to_be_literal._get_arg() == arg

source_file = SourceFile("UnderTest.py", " .toBe(7) ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(7)"
assert str(source_file.parse_to_be_like(1).arg) == "7"

source_file = SourceFile("UnderTest.py", " .toBe( 7 ) ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe( 7 )"
assert str(source_file.parse_to_be_like(1).arg) == "7"

source_file = SourceFile("UnderTest.py", " .toBe(\n7) ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(\n7)"
assert str(source_file.parse_to_be_like(1).arg) == "7"
def python_test_error(source_raw, error_msg):
try:
python_test(source_raw, "unusedArg")
except AssertionError as e:
assert str(e) == error_msg

source_file = SourceFile("UnderTest.py", " .toBe(7\n) ")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe(7\n)"
assert str(source_file.parse_to_be_like(1).arg) == "7"

def todo():
python_test(".toBe_TODO()", ".toBe_TODO()", "")
python_test(" .toBe_TODO() ", ".toBe_TODO()", "")
python_test(" .toBe_TODO( ) ", ".toBe_TODO( )", "")
python_test(" .toBe_TODO( \n ) ", ".toBe_TODO( \n )", "")

def test_single_line_string():
source_file = SourceFile("UnderTest.py", ".toBe('7')")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe('7')"
assert str(source_file.parse_to_be_like(1).arg) == "'7'"

source_file = SourceFile("UnderTest.py", ".toBe('')")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe('')"
assert str(source_file.parse_to_be_like(1).arg) == "''"
def numeric():
python_test(".toBe(7)", ".toBe(7)", "7")
python_test(" .toBe(7)", ".toBe(7)", "7")
python_test(".toBe(7) ", ".toBe(7)", "7")
python_test(" .toBe(7) ", ".toBe(7)", "7")
python_test(" .toBe( 7 ) ", ".toBe( 7 )", "7")
python_test(" .toBe(\n7) ", ".toBe(\n7)", "7")
python_test(" .toBe(7\n) ", ".toBe(7\n)", "7")

source_file = SourceFile("UnderTest.py", ".toBe( '' )")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe( '' )"
assert str(source_file.parse_to_be_like(1).arg) == "''"

source_file = SourceFile("UnderTest.py", ".toBe( \n '' \n )")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg)
== ".toBe( \n '' \n )"
)
assert str(source_file.parse_to_be_like(1).arg) == "''"
def single_line_string():
python_test(".toBe('7')", "'7'")
python_test(".toBe('')", "''")
python_test(".toBe( '' )", "''")
python_test(".toBe( \n '' \n )", "''")
python_test(".toBe( \n '78' \n )", "'78'")
python_test(".toBe('\\'')", "'\\''")

source_file = SourceFile("UnderTest.py", ".toBe( \n '78' \n )")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg)
== ".toBe( \n '78' \n )"
)
assert str(source_file.parse_to_be_like(1).arg) == "'78'"

source_file = SourceFile("UnderTest.py", ".toBe('\\'')")
assert str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe('\\'')"
assert str(source_file.parse_to_be_like(1).arg) == "'\\''"
def multi_line_string():
python_test(".toBe('''7''')", "'''7'''")
python_test(".toBe(''' 7 ''')", "''' 7 '''")
python_test(".toBe('''\n7\n''')", "'''\n7\n'''")
python_test(".toBe(''' ' '' ' ''')", "''' ' '' ' '''")


def test_multi_line_string():
source_file = SourceFile("UnderTest.py", ".toBe('''7''')")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe('''7''')"
def error_unclosed():
python_test_error(
".toBe(", "Appears to be an unclosed function call `.toBe()` on line 1"
)
assert str(source_file.parse_to_be_like(1).arg) == "'''7'''"

source_file = SourceFile("UnderTest.py", ".toBe('''7''')")
assert (
str(source_file.parse_to_be_like(1).function_call_plus_arg) == ".toBe('''7''')"
python_test_error(
".toBe( \n ", "Appears to be an unclosed function call `.toBe()` on line 1"
)
assert str(source_file.parse_to_be_like(1).arg) == "'''7'''"

# source_file = SourceFile("UnderTest.py", ".toBe('''\n7\n''')")
# assert (
# str(source_file.parse_to_be_like(1).function_call_plus_arg)
# == ".toBe('''\n7\n''')"
# )
# assert str(source_file.parse_to_be_like(1).arg) == "'''\n7\n'''"

# source_file = SourceFile("UnderTest.py", ".toBe(''' ' '' ' ''')")
# assert (
# str(source_file.parse_to_be_like(1).function_call_plus_arg)
# == ".toBe(''' ' '' ' ''')"
# )
# assert str(source_file.parse_to_be_like(1).arg) == "''' ' '' ' '''"


def test_error_unclosed():
source_file = SourceFile("UnderTest.py", ".toBe(")
assert_raises_error(
source_file, "Appears to be an unclosed function call `.toBe(` on line 1"
python_test_error(
".toBe_TODO(",
"Appears to be an unclosed function call `.toBe_TODO()` on line 1",
)

source_file = SourceFile("UnderTest.py", ".toBe( \n ")
assert_raises_error(
source_file, "Appears to be an unclosed function call `.toBe(` on line 1"
python_test_error(
".toBe_TODO( \n ",
"Appears to be an unclosed function call `.toBe_TODO()` on line 1",
)

source_file = SourceFile("UnderTest.py", ".toBe_TODO(")
assert_raises_error(
source_file, "Appears to be an unclosed function call `.toBe_TODO(` on line 1"
python_test_error(
".toBe_TODO(')", 'Appears to be an unclosed string literal `"` on line 1'
)

source_file = SourceFile("UnderTest.py", ".toBe_TODO( \n ")
assert_raises_error(
source_file, "Appears to be an unclosed function call `.toBe_TODO(` on line 1"
python_test_error(
".toBe_TODO(''')",
'Appears to be an unclosed multiline string literal `"""` on line 1',
)

# source_file = SourceFile("UnderTest.py", ".toBe_TODO(')")
# assert_raises_error(
# source_file, 'Appears to be an unclosed string literal `"` on line 1'
# )

# source_file = SourceFile("UnderTest.py", ".toBe_TODO(''')")
# assert_raises_error(
# source_file,
# 'Appears to be an unclosed multiline string literal `"""` on line 1',
# )


def test_error_non_primitive():
source_file = SourceFile("UnderTest.py", ".toBe(1 + 1)")
assert_raises_error(
source_file,
"Non-primitive literal in `.toBe(` starting at line 1: error for character `+` on line 1",
def error_non_primitive():
python_test_error(
".toBe(1 + 1)",
"Non-primitive literal in `.toBe()` starting at line 1: error for character `+` on line 1",
)

source_file = SourceFile("UnderTest.py", ".toBe('1' + '1')")
assert_raises_error(
source_file,
"Non-primitive literal in `.toBe(` starting at line 1: error for character `+` on line 1",
python_test_error(
".toBe('1' + '1')",
"Non-primitive literal in `.toBe()` starting at line 1: error for character `+` on line 1",
)

source_file = SourceFile("UnderTest.py", ".toBe('''1''' + '''1''')")
assert_raises_error(
source_file,
"Non-primitive literal in `.toBe(` starting at line 1: error for character `+` on line 1",
python_test_error(
".toBe('''1''' + '''1''')",
"Non-primitive literal in `.toBe()` starting at line 1: error for character `+` on line 1",
)


def assert_raises_error(source_file, error_msg):
try:
source_file.parse_to_be_like(1)
assert False, "Expected an AssertionError, but none was raised."
except AssertionError as e:
assert str(e) == error_msg

0 comments on commit 4e73dd7

Please sign in to comment.