Const tests.
authorRobert Bradshaw <robertwb@gmail.com>
Wed, 19 Sep 2012 06:27:51 +0000 (23:27 -0700)
committerRobert Bradshaw <robertwb@gmail.com>
Wed, 19 Sep 2012 06:27:51 +0000 (23:27 -0700)
tests/compile/const_decl.pyx [new file with mode: 0644]
tests/errors/const_decl_errors.pyx [new file with mode: 0644]
tests/run/cpp_const_method.pyx [new file with mode: 0644]

diff --git a/tests/compile/const_decl.pyx b/tests/compile/const_decl.pyx
new file mode 100644 (file)
index 0000000..38040c6
--- /dev/null
@@ -0,0 +1,7 @@
+# mode: compile
+
+cdef const_args(const int a, const int *b, const (int*) c):
+    print a
+    print b[0]
+    b = NULL    # OK, the pointer itself is not const
+    c[0] = 4    # OK, the value is not const
diff --git a/tests/errors/const_decl_errors.pyx b/tests/errors/const_decl_errors.pyx
new file mode 100644 (file)
index 0000000..23f5195
--- /dev/null
@@ -0,0 +1,21 @@
+# mode: error
+
+cdef const object o
+
+# TODO: This requires making the assignment at declaration time.
+# (We could fake this case by dropping the const here in the C code,
+# as it's not needed for agreeing with external libraries.
+cdef const int x = 10
+
+cdef func(const int a, const int* b, const (int*) c):
+    a = 10
+    b[0] = 100
+    c = NULL
+
+_ERRORS = """
+3:5: Const base type cannot be a Python object
+8:5: Assignment to const 'x'
+11:6: Assignment to const 'a'
+12:5: Assignment to const dereference
+13:6: Assignment to const 'c'
+"""
diff --git a/tests/run/cpp_const_method.pyx b/tests/run/cpp_const_method.pyx
new file mode 100644 (file)
index 0000000..824f7bd
--- /dev/null
@@ -0,0 +1,86 @@
+# cython: experimental_cpp_class_def=True
+# tag: cpp
+
+from libcpp.vector cimport vector
+
+cdef cppclass Wrapper[T]:
+    T value
+    __init__(T &value):
+        this.value = value
+    void set(T &value):
+        this.value = value
+    T get() const:
+        return this.value
+
+
+def test_const_get(int x):
+    """
+    >>> test_const_get(10)
+    10
+    """
+    cdef const Wrapper[int] *wrapper = new Wrapper[int](x)
+    try:
+        return const_get(wrapper[0])
+    finally:
+        del wrapper
+
+cdef int const_get(const Wrapper[int] wrapper):
+    return wrapper.get()
+
+def test_const_ref_get(int x):
+    """
+    >>> test_const_ref_get(100)
+    100
+    """
+    cdef const Wrapper[int] *wrapper = new Wrapper[int](x)
+    try:
+        return const_ref_get(wrapper[0])
+    finally:
+        del wrapper
+
+cdef int const_ref_get(const Wrapper[int] &wrapper):
+    return wrapper.get()
+
+def test_const_pointer_get(int x):
+    """
+    >>> test_const_pointer_get(1000)
+    1000
+    """
+    cdef Wrapper[int] *wrapper = new Wrapper[int](x)
+    cdef const Wrapper[int] *const_wrapper = wrapper
+    try:
+        return const_wrapper.get()
+    finally:
+        del wrapper
+
+
+# TODO: parse vector[Wrapper[int]*]
+ctypedef Wrapper[int] wrapInt
+
+def test_vector_members(py_a, py_b):
+    """
+    >>> test_vector_members([1, 2, 3], [4,5, 6])
+    ([1, 2, 3], 4)
+    """
+    cdef Wrapper[int] *value
+    cdef const Wrapper[int] *const_value
+    cdef vector[const Wrapper[int]*] a
+    cdef vector[wrapInt*] b
+    for x in py_a:
+        a.push_back(new Wrapper[int](x))
+    for x in py_b:
+        b.push_back(new Wrapper[int](x))
+    try:
+        return vector_members(a, b)
+    finally:
+        for const_value in a:
+            del const_value
+        for value in b:
+            del value
+
+cdef vector_members(vector[const Wrapper[int]*] a, const vector[wrapInt*] b):
+    # TODO: Cython-level error.
+    # b[0].set(100)
+    
+    # TODO: const_iterator
+    return [x.get() for x in a], b[0].get()