1

vorgabe tests

This commit is contained in:
ChUrl
2021-08-09 16:36:55 +02:00
parent 744de3c46e
commit d6b6d6105a
9 changed files with 1031 additions and 0 deletions

86
test/test_builtin.py Normal file
View File

@ -0,0 +1,86 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
def test_builtin_simple():
builtincode = """
x = 1
object None:
1
def pass:
None
"""
# construct the builtin module by running builtincode within the context of
# a new empty module
interpreter = Interpreter(builtincode)
w_module = interpreter.make_module()
# the parent of a normal module is the builtin module
builtins = w_module.getparents()[0]
assert builtins.getvalue('x').value == 1
ast = parse("""
tx = x
object a:
pass
ax = a x
""")
interpreter.eval(ast, w_module)
assert w_module.getvalue("ax").value == 1
assert w_module.getvalue("tx").value == 1
def test_inttrait():
builtincode = """
object inttrait:
x = 1
def maybe_fortytwo:
if self:
42
else:
x
"""
interpreter = Interpreter(builtincode)
w_module = interpreter.make_module()
# the parent of a normal module is the builtin module
builtins = w_module.getparents()[0]
inttrait = builtins.getvalue("inttrait")
ast = parse("""
x = 5 x # this returns 1, because it looks in the inttrait defined above
m0 = 0 maybe_fortytwo
m1 = x maybe_fortytwo
inttrait x = 2
m2 = 0 maybe_fortytwo
tr = inttrait
""")
interpreter.eval(ast, w_module)
x = w_module.getvalue("x")
assert w_module.getvalue("tr") is inttrait
# the inttrait is defined in the builtin module, so its __parent__ is that
# module
assert inttrait.getparents() == [builtins]
assert x.value == 1
assert x.getparents() == [inttrait]
assert w_module.getvalue("m0").value == 1
assert w_module.getvalue("m1").value == 42
assert w_module.getvalue("m2").value == 2
def test_builtin_default():
ast = parse("""
def sumupto(x):
r = 0
while x:
r = r add(x)
x = x add(-1)
r
x = sumupto(100)
""")
# the constructor is called without arguments, so the default builtins are
# used
interpreter = Interpreter()
# test that the default inttrait defines a method ``add``
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 5050

206
test/test_bytecode.py Normal file
View File

@ -0,0 +1,206 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
empty_builtins = """
1
"""
def test_assignment():
ast = parse("""
x = 1
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 1
def test_negative_intliteral():
ast = parse("""
x = -1
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == -1
def test_huge_intliteral():
ast = parse("""
x = 10000
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 10000
def test_huge_negative_intliteral():
ast = parse("""
x = -10000
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == -10000
def test_primitive():
ast = parse("""
x = 1 $int_add(2)
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 3
def test_pop():
ast = parse("""
x = 1 # the result of this will be popped from the stack
x = 2
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 2
def test_condition():
ast = parse("""
x = 1
if x:
x = 2
else:
x = 3
if 0:
y = 3
else:
y = 4
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 2
assert w_module.getvalue("y").value == 4
def test_objectdefinition_simple():
ast = parse("""
object x:
a = 1
b = 2
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").getvalue("a").value == 1
assert w_module.getvalue("x").getvalue("b").value == 2
def test_objectdefinition_parents():
ast = parse("""
object x:
a = 1
b = 2
object y(parent=x):
b = 3
a = y a
b = y b
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("a").value == 1
assert w_module.getvalue("b").value == 3
def test_objectdefinition___parent__():
ast = parse("""
object x:
a = 1
b = 2
object y(__parent__=x):
b = 3
a = y a
b = y b
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("a").value == 1
assert w_module.getvalue("b").value == 3
def test_functiondefinition_noargs():
ast = parse("""
def f:
if x:
1
else:
2
x = 0
x = f
y = f
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 2
assert w_module.getvalue("y").value == 1
def test_functiondefinition_args():
ast = parse("""
def f(x):
if x:
1
else:
2
x = f(0)
y = f(1)
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 2
assert w_module.getvalue("y").value == 1
def test_whileloop():
ast = parse("""
def f(x):
sum = 0
while x:
sum = sum $int_add(x)
x = x $int_add(-1)
sum
x = f(100)
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").value == 5050
def test_method_cascade():
ast = parse("""
object x:
a = 1
object y:
a = 2
x next = y
y next = x
a = x next next next next next next a
b = x next next next next next next next a
""")
interpreter = Interpreter(empty_builtins)
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("a").value == 1
assert w_module.getvalue("b").value == 2

123
test/test_interpreter.py Normal file
View File

@ -0,0 +1,123 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
#
# The Interpreter class needs a method 'eval(ast, w_context)' that is
# doing "AST visiting", as follows:
#
# def eval(self, ast, w_context):
# method = getattr(self, "eval_" + ast.__class__.__name__)
# return method(ast, w_context)
#
# This calls a method called "eval_Xxx" on self for every class
# called Xxx of the simpleast.py module.
#
def test_simplxe():
ast = parse("""
10
11
12
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
def test_simple():
ast = parse("""
k = 10
j = 11
i = 12
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i").value == 12
assert w_module.getvalue("j").value == 11
assert w_module.getvalue("k").value == 10
def test_if():
ast = parse("""
k = 10
if k:
j = 11
else:
i = 12
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i") is None
assert w_module.getvalue("j").value == 11
assert w_module.getvalue("k").value == 10
def test_def():
ast = parse("""
def f(x, y):
if x:
x
else:
y
i = f(6, 3)
j = f(0, 9)
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i").value == 6
assert w_module.getvalue("j").value == 9
def test_object():
ast = parse("""
object x:
i = 4
j = i
object z:
i = 5
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("x").getvalue("i").value == 4
assert w_module.getvalue("x").getvalue("j").value == 4
assert w_module.getvalue("x").getvalue("z").getvalue("i").value == 5
def test_obscure_recursion():
ast = parse("""
object a:
def f(a):
if a:
x = 5
a f(0)
else:
x = 7
x
i = a f(a)
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i").value == 5
def test_assign():
ast = parse("""
object a:
b = 5
def set(n):
self b = n
a set(7)
i = a b
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i").value == 7

82
test/test_method.py Normal file
View File

@ -0,0 +1,82 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
def test_assign():
ast = parse("""
object a:
b = 5
def set(n):
self b = n
a set(7)
i = a b
""")
w_module = W_NormalObject()
interpreter = Interpreter()
interpreter.eval(ast, w_module)
assert w_module.getvalue("i").value == 7
def test_method_simple():
ast = parse("""
object a:
x = 11
def f:
self x
object b:
__parent__ = a
x = 22
af = a f # a is the receiver, therefore self is a in the method
bf = b f # b is the receiver, therefore self is b in the method
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("af").value == 11
assert w_module.getvalue("bf").value == 22
def test_method_complex():
ast = parse("""
k = 10
object a:
x = 11
y = 22
def f(a, b):
if a:
if b:
a
else:
k
else:
if b:
self x
else:
self y
object b:
__parent__ = a
y = 55
af11 = a f(1, 1)
af10 = a f(1, 0)
af01 = a f(0, 1)
af00 = a f(0, 0)
k = 908
bf11 = b f(1, 1)
bf10 = b f(1, 0)
bf01 = b f(0, 1)
bf00 = b f(0, 0)
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("af11").value == 1
assert w_module.getvalue("af10").value == 10
assert w_module.getvalue("af01").value == 11
assert w_module.getvalue("af00").value == 22
assert w_module.getvalue("bf11").value == 1
assert w_module.getvalue("bf10").value == 908
assert w_module.getvalue("bf01").value == 11
assert w_module.getvalue("bf00").value == 55

38
test/test_objmodel.py Normal file
View File

@ -0,0 +1,38 @@
from objmodel import W_Integer, W_NormalObject
def test_normalobject():
w1 = W_NormalObject()
# 'setvalue' and 'getvalue' write and read the attributes by name.
w1.setvalue('abc', W_Integer(6))
w2 = w1.getvalue('abc')
assert isinstance(w2, W_Integer)
assert w2.value == 6
# a missing attribute...
assert w1.getvalue('bcd') is None
def test_integer():
w1 = W_Integer(5)
assert w1.value == 5
# W_Integer objects cannot have custom attributes,
# so getvalue() returns None.
assert w1.getvalue('abc') is None
def test_istrue():
assert W_Integer(5).istrue() is True
assert W_Integer(0).istrue() is False
assert W_Integer(-1).istrue() is True
# for now, only W_Integer(0) is false; all the other objects are true.
assert W_NormalObject().istrue() is True
def test_clone():
w1 = W_NormalObject()
w1.setvalue('abc', W_Integer(6))
w2 = w1.clone()
assert w2.getvalue('abc').value == 6
w2.setvalue('abc', W_Integer(99))
assert w2.getvalue('abc').value == 99
assert w1.getvalue('abc').value == 6 # still the old value

205
test/test_parent.py Normal file
View File

@ -0,0 +1,205 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
def test_implicit_parent():
ast = parse("""
k = 10
object a:
z = k
az = a z
""")
interpreter = Interpreter()
# make_module creates a new empty W_NormalObject for now
# this will change later
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("a").getvalue('__parent__') is w_module
assert w_module.getvalue("a").getparents() == [w_module]
assert w_module.getvalue("az").value == 10
def test_implicit_parent_method():
ast = parse("""
k = 10
def f(x):
if x:
k
else:
1
f1 = f(1)
f0 = f(0)
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("f1").value == 10
assert w_module.getvalue("f0").value == 1
def test_shadow_parent_attribute():
ast = parse("""
k = 10
def f(x):
if x:
k = 41
k
f1 = f(1)
f0 = f(0)
object a:
k = 11
ak = a k
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("f1").value == 41
assert w_module.getvalue("f0").value == 10
assert w_module.getvalue("ak").value == 11
assert w_module.getvalue("k").value == 10
def test_capture():
ast = parse("""
k = 10
object a:
j = k
k = 11
aj = a j
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("aj").value == 10
def test_override__parent__():
ast = parse("""
k = 10
object a:
x = 1
y = 2
z = k
object b:
__parent__ = a
y = 5
z = y
ax = a x
ay = a y
az = a z
bx = b x
by = b y
bz = b z
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
a = w_module.getvalue("a")
assert a.getvalue('__parent__') is w_module
assert w_module.getvalue("b").getvalue('__parent__') is a
assert w_module.getvalue("b").getparents() == [a]
assert w_module.getvalue("ax").value == 1
assert w_module.getvalue("ay").value == 2
assert w_module.getvalue("az").value == 10
assert w_module.getvalue("bx").value == 1
assert w_module.getvalue("by").value == 5
assert w_module.getvalue("bz").value == 5
def test_parent_syntax():
ast = parse("""
object a:
x = 11
object b(parent=a):
x = 22
af = a x
bf = b x
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
a = w_module.getvalue("a")
b = w_module.getvalue("b")
assert a.getvalue('__parent__') is w_module
assert b.getvalue('__parent__') is w_module
assert b.getvalue('parent') is a
assert a.getparents() == [w_module]
assert b.getparents() == [a, w_module]
assert w_module.getvalue("af").value == 11
assert w_module.getvalue("bf").value == 22
def test_parent_syntax_multiple():
ast = parse("""
a = 1
b = 2
c = 3
d = 4
object x:
b = 5
c = 6
d = 7
object y:
c = 8
d = 9
object z(p1=y, p2=x):
d = 10
za = z a
zb = z b
zc = z c
zd = z d
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
x = w_module.getvalue("x")
y = w_module.getvalue("y")
z = w_module.getvalue("z")
assert x.getvalue('__parent__') is w_module
assert y.getvalue('__parent__') is w_module
assert z.getvalue('__parent__') is w_module
assert z.getvalue('p1') is y
assert z.getvalue('p2') is x
assert x.getparents() == [w_module]
assert y.getparents() == [w_module]
assert z.getparents() == [y, x, w_module]
assert w_module.getvalue("za").value == 1
assert w_module.getvalue("zb").value == 5
assert w_module.getvalue("zc").value == 8
assert w_module.getvalue("zd").value == 10
def test_wrong_hierarchy_error():
ast = parse("""
object base:
x = 1
object sub(p1=base):
x = 2
def mayhem:
object bad(p1=base, p2=sub):
x = 3
bad x
result = mayhem
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
py.test.raises(TypeError, interpreter.eval, ast, w_module)
def test_duplicate_base_error():
ast = parse("""
object base:
x = 1
object sub(p1=base, p2=base):
x = 2
y = sub x
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
py.test.raises(TypeError, interpreter.eval, ast, w_module)

42
test/test_primitive.py Normal file
View File

@ -0,0 +1,42 @@
import py
from simpleparser import parse
from objmodel import W_NormalObject
from interpreter import Interpreter
def test_primitive():
ast = parse("""
k = 10 $int_add(31)
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("k").value == 41
def test_primitive_error():
ast = parse("""
k = 10 $int_add(31, 12)
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
with py.test.raises(TypeError):
interpreter.eval(ast, w_module)
def test_loop():
ast = parse("""
def f(x):
r = 0
while x:
r = r $int_add(x)
x = x $int_add(-1)
r
y = f(100)
""")
interpreter = Interpreter()
w_module = interpreter.make_module()
interpreter.eval(ast, w_module)
assert w_module.getvalue("y").value == 5050

100
test/test_simplelexer.py Normal file
View File

@ -0,0 +1,100 @@
from simplelexer import lex
# Every insturction ends with an newline
def test_single_quoted_string():
for s in ["""'abc'""",
"""'ab"c'""",
"""'ab\\'c'""",
]:
tokens = lex(s)
token, newline, eof = tokens
assert token.name == 'String'
assert newline.name == 'Newline'
assert eof.name == 'EOF'
def test_number():
for s in ["0",
"+1",
"-1",
"-1123123",
]:
tokens = lex(s)
token, newline, eof = tokens
assert tokens[0].name == 'Number'
assert token.name == 'Number'
assert newline.name == 'Newline'
assert eof.name == 'EOF'
def test_name():
for s in ["abc",
"_",
"a_0",
"_0",
]:
tokens = lex(s)
token, newline, eof = tokens
assert tokens[0].name == 'Name'
assert token.name == 'Name'
assert newline.name == 'Newline'
assert eof.name == 'EOF'
def test_primitvename():
for s in ["$abc",
"$_",
"$a_0",
"$_0",
]:
tokens = lex(s)
token, newline, eof = tokens
assert tokens[0].name == 'PrimitiveName'
assert token.name == 'PrimitiveName'
assert newline.name == 'Newline'
assert eof.name == 'EOF'
def test_long():
for s, numtoken in [
("if x:\n print x", 10),
("if x:#foo\n x abc = 7", 12),
("1 a \\\n 2", 5)
]:
tokens = lex(s)
assert len(tokens) == numtoken
def test_indentation():
s = """a
b
c
d
#some comment
e
f
"""
tokens = lex(s)
assert [t.name for t in tokens] == ["Name", "Newline", "Name", "Newline",
"Indent", "Name", "Newline", "Indent",
"Name", "Newline", "Dedent", "Name",
"Newline", "Indent", "Name", "Newline",
"Dedent", "Dedent", "EOF"]
# This is only one line! The \ is used for line continuation
def test_linecont():
s = "a a \\\n b"
tokens = lex(s)
assert [t.name for t in tokens] == ["Name", "Name", "Name", "Newline",
"EOF"]
# newline token between brackets are ignored ...
def test_parenthesis():
s = "(a = \n b)"
tokens = lex(s)
assert [t.name for t in tokens] == ["OpenBracket", "Name", "Assign", "Name",
"CloseBracket", "Newline", "EOF"]
# ... unless you insert a comment
def test_comment():
s = "(a = # foo this is a comment \n b)"
tokens = lex(s)
assert [t.name for t in tokens] == ["OpenBracket", "Name", "Assign", "Name",
"CloseBracket", "Newline", "EOF"]

149
test/test_simpleparser.py Normal file
View File

@ -0,0 +1,149 @@
import py
from simpleparser import ParseError, parse
from simplelexer import lex
from simpleast import *
def raisesparserror(source):
with py.test.raises(ParseError) as excinfo:
parse(source)
print(excinfo.value.nice_error_message())
def test_expression():
ast = parse("a b c")
ast1 = MethodCall(MethodCall(MethodCall(ImplicitSelf(), "a"), "b"), "c")
assert ast == Program([ExprStatement(ast1)])
ast = parse("a f(1, a b c, 3,)")
ast2 = Program([ExprStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "f", [
IntLiteral(1), ast1, IntLiteral(3)]))])
assert ast == ast2
def test_expression2():
ast = parse("$a $b $c")
ast1 = PrimitiveMethodCall(PrimitiveMethodCall(
PrimitiveMethodCall(ImplicitSelf(), "$a"), "$b"), "$c")
assert ast == Program([ExprStatement(ast1)])
ast = parse("$a $f(1, $a $b $c, 3,)")
assert ast == Program([ExprStatement(PrimitiveMethodCall(
PrimitiveMethodCall(ImplicitSelf(), "$a"), "$f", [
IntLiteral(1), ast1, IntLiteral(3)]))])
def test_simplestatement():
ast = parse("a\n")
ast1 = Program([ExprStatement(MethodCall(ImplicitSelf(), "a"))])
assert ast == ast1
ast = parse("a = 4 b\n")
ast1 = Program([Assignment(ImplicitSelf(), "a", MethodCall(IntLiteral(4), "b"))])
assert ast == ast1
ast = raisesparserror("a(1) = 4 b\n")
ast = raisesparserror("1 = 4 b\n")
def test_error():
ast = raisesparserror("a add 2\n")
def test_if():
ast = parse("""if a and(b):
a b
""")
ast1 = Program([IfStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "and",
[MethodCall(ImplicitSelf(), "b")]),
Program([ExprStatement(
MethodCall(MethodCall(ImplicitSelf(), "a"),
"b"))]))])
assert ast1 == ast
ast = parse("""if a and(b):
a b
else:
b
""")
ast1 = Program([IfStatement(MethodCall(MethodCall(ImplicitSelf(), "a"), "and",
[MethodCall(ImplicitSelf(), "b")]),
Program([ExprStatement(
MethodCall(MethodCall(ImplicitSelf(), "a"),
"b"))]),
Program([ExprStatement(
MethodCall(ImplicitSelf(), "b"))]))])
assert ast1 == ast
def test_while():
ast = parse("""
while i:
i = i sub(1)
""")
ast1 = Program([WhileStatement(MethodCall(ImplicitSelf(), "i"),
Program([Assignment(ImplicitSelf(), "i",
MethodCall(MethodCall(ImplicitSelf(), "i"),
"sub",
[IntLiteral(1)]))]))])
assert ast1 == ast
def test_object():
ast = parse("""
object a:
i = 1
if i:
j = 2
""")
ast1 = Program([ObjectDefinition("a", Program([
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
]))
]))])
assert ast1 == ast
ast = parse("""
object a(parent=1):
i = 1
if i:
j = 2
""")
ast1 = Program([ObjectDefinition("a", Program([
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
]))
]),
["parent"],
[IntLiteral(1)])])
assert ast1 == ast
def test_def():
ast = parse("""
def f(x, y, z):
i = 1
if i:
j = 2
""")
ast1 = Program([FunctionDefinition("f", ["x", "y", "z"], Program([
Assignment(ImplicitSelf(), "i", IntLiteral(1)),
IfStatement(MethodCall(ImplicitSelf(), "i"), Program([
Assignment(ImplicitSelf(), "j", IntLiteral(2)),
]))
]))])
assert ast1 == ast
def test_object2():
ast = parse("""
object None:
1
""")
ast = parse("""
def pass:
None
""")
ast = parse("""
object None:
1
def pass:
None
""")