Skip to content

Commit 2d5d870

Browse files
committed
added correct tests for textblocks
1 parent 495f85b commit 2d5d870

File tree

6 files changed

+60
-23
lines changed

6 files changed

+60
-23
lines changed

src/jast/_jast.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def __copy__(self):
3939
"""
4040
obj = jtype(self).__new__(self.__class__)
4141
obj.__dict__.update(self.__dict__)
42+
for field, value in self:
43+
if isinstance(value, list):
44+
setattr(obj, field, getattr(self, field)[:])
4245
return obj
4346

4447

@@ -213,21 +216,16 @@ def __copy__(self):
213216
return StringLiteral(self.value)
214217

215218

216-
class TextBlock(literal, str):
219+
class TextBlock(literal):
217220
"""
218221
Represents a text body literal in the Java AST.
219222
"""
220223

221224
def __init__(self, value: str, *vargs, **kwargs):
222225
super().__init__(value, *vargs, **kwargs)
223226

224-
def __new__(cls, value, *vargs, **kwargs):
225-
obj = str.__new__(cls, value)
226-
TextBlock.__init__(obj, value, *vargs, **kwargs)
227-
return obj
228-
229227
def __copy__(self):
230-
return TextBlock(self.value)
228+
return TextBlock(self.value[:])
231229

232230

233231
class NullLiteral(literal):

src/jast/_parser/_convert.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,17 @@ def visitLiteral(self, ctx: JavaParser.LiteralContext) -> jast.literal:
782782
elif ctx.NULL_LITERAL():
783783
return jast.NullLiteral()
784784
else:
785-
return jast.TextBlock(value=ctx.getText()[3:-3])
785+
text = ctx.getText()[3:-3]
786+
lines = text.split("\n")[1:]
787+
min_spaces = min(
788+
len(line) - len(line.lstrip()) for line in lines if line.strip()
789+
)
790+
return jast.TextBlock(
791+
value=[
792+
line[min_spaces:] if line.strip() else line.strip()
793+
for line in lines
794+
]
795+
)
786796

787797
def visitIntegerLiteral(
788798
self, ctx: JavaParser.IntegerLiteralContext

src/jast/_unparse.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,24 @@ def seperator(self):
7474
else:
7575
self.write(" ")
7676

77-
def maybe_newline(self):
77+
def maybe_newline(self, force_newline: bool = False):
7878
"""
7979
Add a newline if it isn't the start of the generated source and the indent is not negative.
80+
:param force_newline: If True, a newline is always added.
8081
"""
8182
if self._source:
82-
self.write(self.seperator())
83+
if force_newline:
84+
self.write("\n")
85+
else:
86+
self.write(self.seperator())
8387

84-
def fill(self, text=""):
88+
def fill(self, text="", force_newline: bool = False):
8589
"""
8690
Indent a piece of text and write it to the source.
87-
:param text:
91+
:param text: The text to indent.
92+
:param force_newline: If True, a newline is always added.
8893
"""
89-
self.maybe_newline()
94+
self.maybe_newline(force_newline)
9095
if self._indent_spaces >= 0:
9196
self.write(" " * self._indent_spaces * self._indent)
9297
self.write(text)
@@ -216,7 +221,10 @@ def visit_StringLiteral(self, node: jast.StringLiteral):
216221
self.write(f'"{node.value}"')
217222

218223
def visit_TextBlock(self, node: jast.TextBlock):
219-
self.write(f'"""{node.value}"""')
224+
with self.delimit('"""', '"""'):
225+
with self.block():
226+
for line in node.value:
227+
self.fill(line, force_newline=True)
220228

221229
def visit_NullLiteral(self, node: jast.NullLiteral):
222230
self.write("null")

tests/test_jast.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ def test_StringLiteral(self):
8585
self._test_iteration(string_literal)
8686

8787
def test_TextBlock(self):
88-
text_block = jast.TextBlock("foo")
88+
text_block = jast.TextBlock(["foo"])
8989
self.assertIsInstance(text_block, jast.TextBlock)
90-
self.assertIsInstance(text_block, str)
91-
self.assertEqual("foo", text_block)
90+
self.assertEqual(["foo"], text_block.value)
9291
self._test_iteration(text_block)
9392

9493
def test_NullLiteral(self):

tests/test_parse.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import itertools
2-
import unittest
32

43
from parameterized import parameterized
54

@@ -132,12 +131,25 @@ def test_StringLiteral(self):
132131
self.assertIsInstance(string_literal.value, jast.StringLiteral)
133132
self.assertEqual("foo", string_literal.value.value)
134133

135-
@unittest.skip("TextBlock does not work as expected")
136134
def test_TextBlock(self):
137-
text_block = jast.parse('"""foo"""', jast.ParseMode.EXPR)
135+
text_block = jast.parse('"""\nfoo"""', jast.ParseMode.EXPR)
138136
self.assertIsInstance(text_block, jast.Constant)
139137
self.assertIsInstance(text_block.value, jast.TextBlock)
140-
self.assertEqual("foo", text_block.value.value)
138+
self.assertEqual(["foo"], text_block.value.value)
139+
140+
def test_TextBlock_new_line(self):
141+
text_block = jast.parse('"""\nfoo\n"""', jast.ParseMode.EXPR)
142+
self.assertIsInstance(text_block, jast.Constant)
143+
self.assertIsInstance(text_block.value, jast.TextBlock)
144+
self.assertEqual(["foo", ""], text_block.value.value)
145+
146+
def test_TextBlock_different_indents(self):
147+
text_block = jast.parse(
148+
'"""\n foo\n\t bar\n \n\t\t\tbaz\n """', jast.ParseMode.EXPR
149+
)
150+
self.assertIsInstance(text_block, jast.Constant)
151+
self.assertIsInstance(text_block.value, jast.TextBlock)
152+
self.assertEqual(["foo", " bar", "", "\tbaz", ""], text_block.value.value)
141153

142154
def test_Null(self):
143155
null = jast.parse("null", jast.ParseMode.EXPR)

tests/test_unparse.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,18 @@ def test_StringLiteral(self):
5656
self.assertEqual('"foo"', jast.unparse(tree))
5757

5858
def test_TextBlock(self):
59-
tree = jast.TextBlock("foo")
60-
self.assertEqual('"""foo"""', jast.unparse(tree))
59+
tree = jast.TextBlock(["foo"])
60+
self.assertEqual('"""\nfoo"""', jast.unparse(tree, indent=-1))
61+
62+
def test_TextBlock_new_line(self):
63+
tree = jast.TextBlock(["foo", ""])
64+
self.assertEqual('"""\n foo\n """', jast.unparse(tree))
65+
66+
def test_TextBlock_different_indents(self):
67+
tree = jast.TextBlock(["foo", " bar", "", "\tbaz", ""])
68+
self.assertEqual(
69+
'"""\n foo\n bar\n \n \tbaz\n """', jast.unparse(tree)
70+
)
6171

6272
def test_NullLiteral(self):
6373
tree = jast.NullLiteral()

0 commit comments

Comments
 (0)