From 40d43ea88dfff431dd863146dd2e62ea8c24683e Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Wed, 22 Apr 2015 23:18:28 +0100
Subject: [PATCH] tests: Add more tests for viper, including tests for
 ViperTypeError's.

---
 tests/micropython/viper_cond.py           | 12 ++++-
 tests/micropython/viper_cond.py.exp       |  1 +
 tests/micropython/viper_error.py          | 55 ++++++++++++++++++++---
 tests/micropython/viper_error.py.exp      | 14 +++++-
 tests/micropython/viper_misc.py           | 37 ++++++++++++---
 tests/micropython/viper_misc.py.exp       |  4 ++
 tests/micropython/viper_ptr16_load.py     |  6 ++-
 tests/micropython/viper_ptr16_load.py.exp |  2 +-
 tests/micropython/viper_ptr8_load.py      |  6 ++-
 tests/micropython/viper_ptr8_load.py.exp  |  2 +-
 tests/micropython/viper_ptr8_store.py     |  9 +++-
 tests/micropython/viper_ptr8_store.py.exp |  3 +-
 12 files changed, 131 insertions(+), 20 deletions(-)

diff --git a/tests/micropython/viper_cond.py b/tests/micropython/viper_cond.py
index 258a37812..a168afce9 100644
--- a/tests/micropython/viper_cond.py
+++ b/tests/micropython/viper_cond.py
@@ -1,4 +1,14 @@
-# using a bool as a conditional
+# using False as a conditional
+@micropython.viper
+def f():
+    x = False
+    if x:
+        pass
+    else:
+        print("not x", x)
+f()
+
+# using True as a conditional
 @micropython.viper
 def f():
     x = True
diff --git a/tests/micropython/viper_cond.py.exp b/tests/micropython/viper_cond.py.exp
index 244817f1f..dff710393 100644
--- a/tests/micropython/viper_cond.py.exp
+++ b/tests/micropython/viper_cond.py.exp
@@ -1,2 +1,3 @@
+not x False
 x True
 y 1
diff --git a/tests/micropython/viper_error.py b/tests/micropython/viper_error.py
index 514acebd7..0762f5079 100644
--- a/tests/micropython/viper_error.py
+++ b/tests/micropython/viper_error.py
@@ -1,11 +1,54 @@
-# test syntax errors specific to viper code generation
+# test syntax and type errors specific to viper code generation
 
-def test_syntax(code):
+def test(code):
     try:
         exec(code)
-    except SyntaxError:
-        print("SyntaxError")
+    except (SyntaxError, ViperTypeError) as e:
+        print(repr(e))
 
 # viper: annotations must be identifiers
-test_syntax("@micropython.viper\ndef f(a:1): pass")
-test_syntax("@micropython.viper\ndef f() -> 1: pass")
+test("@micropython.viper\ndef f(a:1): pass")
+test("@micropython.viper\ndef f() -> 1: pass")
+
+# local used before type known
+test("""
+@micropython.viper
+def f():
+    print(x)
+    x = 1
+""")
+
+# type mismatch storing to local
+test("""
+@micropython.viper
+def f():
+    x = 1
+    y = []
+    x = y
+""")
+
+# can't implicitly convert type to bool
+test("""
+@micropython.viper
+def f():
+    x = ptr(0)
+    if x:
+        pass
+""")
+
+# incorrect return type
+test("@micropython.viper\ndef f() -> int: return []")
+
+# can't do binary op between incompatible types
+test("@micropython.viper\ndef f(): 1 + []")
+
+# can't load
+test("@micropython.viper\ndef f(): 1[0]")
+test("@micropython.viper\ndef f(): 1[x]")
+
+# can't store
+test("@micropython.viper\ndef f(): 1[0] = 1")
+test("@micropython.viper\ndef f(): 1[x] = 1")
+
+# must raise an object
+test("@micropython.viper\ndef f(): raise 1")
diff --git a/tests/micropython/viper_error.py.exp b/tests/micropython/viper_error.py.exp
index 5275689b4..ad1ba34c6 100644
--- a/tests/micropython/viper_error.py.exp
+++ b/tests/micropython/viper_error.py.exp
@@ -1,2 +1,12 @@
-SyntaxError
-SyntaxError
+SyntaxError('parameter annotation must be an identifier',)
+SyntaxError('return annotation must be an identifier',)
+ViperTypeError("local 'x' used before type known",)
+ViperTypeError("local 'x' has type 'int' but source is 'object'",)
+ViperTypeError("can't implicitly convert 'ptr' to 'bool'",)
+ViperTypeError("return expected 'int' but got 'object'",)
+ViperTypeError("can't do binary op between 'int' and 'object'",)
+ViperTypeError("can't load from 'int'",)
+ViperTypeError("can't load from 'int'",)
+ViperTypeError("can't store to 'int'",)
+ViperTypeError("can't store to 'int'",)
+ViperTypeError('must raise an object',)
diff --git a/tests/micropython/viper_misc.py b/tests/micropython/viper_misc.py
index 25dd47355..e8b96b9c1 100644
--- a/tests/micropython/viper_misc.py
+++ b/tests/micropython/viper_misc.py
@@ -12,6 +12,25 @@ def viper_object(x:object, y:object) -> object:
     return x + y
 print(viper_object(1, 2))
 
+# return None as non-object (should return 0)
+@micropython.viper
+def viper_ret_none() -> int:
+    return None
+print(viper_ret_none())
+
+# 3 args
+@micropython.viper
+def viper_3args(a:int, b:int, c:int) -> int:
+    return a + b + c
+print(viper_3args(1, 2, 3))
+
+# 4 args
+@micropython.viper
+def viper_4args(a:int, b:int, c:int, d:int) -> int:
+    return a + b + c + d
+# viper call with 4 args not yet supported
+#print(viper_4args(1, 2, 3, 4))
+
 # a local (should have automatic type int)
 @micropython.viper
 def viper_local(x:int) -> int:
@@ -25,6 +44,13 @@ def viper_no_annotation(x, y):
     return x * y
 print(viper_no_annotation(4, 5))
 
+# unsigned ints
+@micropython.viper
+def viper_uint() -> uint:
+    return uint(-1)
+import sys
+print(viper_uint() == (sys.maxsize << 1 | 1))
+
 # a for loop
 @micropython.viper
 def viper_for(a:int, b:int) -> int:
@@ -48,6 +74,12 @@ def viper_print(x, y:int):
     print(x, y + 1)
 viper_print(1, 2)
 
+# convert constants to objects in tuple
+@micropython.viper
+def viper_tuple_consts(x):
+    return (x, 1, False, True)
+print(viper_tuple_consts(0))
+
 # making a tuple from an object and an int
 @micropython.viper
 def viper_tuple(x, y:int):
@@ -75,11 +107,6 @@ try:
 except OSError as e:
     print(repr(e))
 
-# this doesn't work at the moment
-#@micropython.viper
-#def g() -> uint:
-#    return -1
-
 # calling GC after defining the function
 @micropython.viper
 def viper_gc() -> int:
diff --git a/tests/micropython/viper_misc.py.exp b/tests/micropython/viper_misc.py.exp
index a65bd2c52..7859d39e5 100644
--- a/tests/micropython/viper_misc.py.exp
+++ b/tests/micropython/viper_misc.py.exp
@@ -1,10 +1,14 @@
 6
 3
+0
+6
 7
 20
+True
 49994955
 1 1
 1 3
+(0, 1, False, True)
 (1, 3)
 [1, 3]
 [1, 3]
diff --git a/tests/micropython/viper_ptr16_load.py b/tests/micropython/viper_ptr16_load.py
index 06ce7db15..81a413c40 100644
--- a/tests/micropython/viper_ptr16_load.py
+++ b/tests/micropython/viper_ptr16_load.py
@@ -5,6 +5,10 @@
 def get(src:ptr16) -> int:
     return src[0]
 
+@micropython.viper
+def get1(src:ptr16) -> int:
+    return src[1]
+
 @micropython.viper
 def memadd(src:ptr16, n:int) -> int:
     sum = 0
@@ -14,5 +18,5 @@ def memadd(src:ptr16, n:int) -> int:
 
 b = bytearray(b'1234')
 print(b)
-print(get(b))
+print(get(b), get1(b))
 print(memadd(b, 2))
diff --git a/tests/micropython/viper_ptr16_load.py.exp b/tests/micropython/viper_ptr16_load.py.exp
index 68fd9e80c..caf475489 100644
--- a/tests/micropython/viper_ptr16_load.py.exp
+++ b/tests/micropython/viper_ptr16_load.py.exp
@@ -1,3 +1,3 @@
 bytearray(b'1234')
-12849
+12849 13363
 26212
diff --git a/tests/micropython/viper_ptr8_load.py b/tests/micropython/viper_ptr8_load.py
index 98c163f8e..0ccf8a1d7 100644
--- a/tests/micropython/viper_ptr8_load.py
+++ b/tests/micropython/viper_ptr8_load.py
@@ -4,6 +4,10 @@
 def get(src:ptr8) -> int:
     return src[0]
 
+@micropython.viper
+def get1(src:ptr8) -> int:
+    return src[1]
+
 @micropython.viper
 def memadd(src:ptr8, n:int) -> int:
     sum = 0
@@ -22,6 +26,6 @@ def memadd2(src_in) -> int:
 
 b = bytearray(b'1234')
 print(b)
-print(get(b))
+print(get(b), get1(b))
 print(memadd(b, 4))
 print(memadd2(b))
diff --git a/tests/micropython/viper_ptr8_load.py.exp b/tests/micropython/viper_ptr8_load.py.exp
index aeab88da1..d899bbee7 100644
--- a/tests/micropython/viper_ptr8_load.py.exp
+++ b/tests/micropython/viper_ptr8_load.py.exp
@@ -1,4 +1,4 @@
 bytearray(b'1234')
-49
+49 50
 202
 202
diff --git a/tests/micropython/viper_ptr8_store.py b/tests/micropython/viper_ptr8_store.py
index fc24290c9..5a8622eb1 100644
--- a/tests/micropython/viper_ptr8_store.py
+++ b/tests/micropython/viper_ptr8_store.py
@@ -4,6 +4,10 @@
 def set(dest:ptr8, val:int):
     dest[0] = val
 
+@micropython.viper
+def set1(dest:ptr8, val:int):
+    dest[1] = val
+
 @micropython.viper
 def memset(dest:ptr8, val:int, n:int):
     for i in range(n):
@@ -19,7 +23,10 @@ def memset2(dest_in, val:int):
 b = bytearray(4)
 print(b)
 
-set(b, 42)
+set(b, 41)
+print(b)
+
+set1(b, 42)
 print(b)
 
 memset(b, 43, len(b))
diff --git a/tests/micropython/viper_ptr8_store.py.exp b/tests/micropython/viper_ptr8_store.py.exp
index 30ca5b10e..b2fbe426c 100644
--- a/tests/micropython/viper_ptr8_store.py.exp
+++ b/tests/micropython/viper_ptr8_store.py.exp
@@ -1,4 +1,5 @@
 bytearray(b'\x00\x00\x00\x00')
-bytearray(b'*\x00\x00\x00')
+bytearray(b')\x00\x00\x00')
+bytearray(b')*\x00\x00')
 bytearray(b'++++')
 bytearray(b',,,,')
-- 
GitLab