text: from __future__ import print_function
  from __future__ import absolute_import
  
  import pytest
  
  __license__ = """
  
  Copyright (c) 2012-2014, Uwe Schmitt, ETH Zurich, all rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
  
  Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.
  
  Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.
  
  Neither the name of the mineway GmbH nor the names of its contributors may be
  used to endorse or promote products derived from this software without specific
  prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  """
  
  import autowrap.DeclResolver
  import autowrap.CodeGenerator
  import autowrap.PXDParser
  import autowrap.Utils
  import autowrap.Code
  import autowrap
  
  import os
  import math
  import copy
  import sys
  
  from .utils import expect_exception
  
  test_files = os.path.join(os.path.dirname(__file__), "test_files")
  
  def test_minimal():
  
      from autowrap.ConversionProvider import (TypeConverterBase,
                                               special_converters)
  
      class SpecialIntConverter(TypeConverterBase):
  
          def get_base_types(self):
              return "int",
  
          def matches(self, cpp_type):
              return cpp_type.is_unsigned
  
          def matching_python_type(self, cpp_type):
              return "int"
  
          def type_check_expression(self, cpp_type, argument_var):
              return "isinstance(%s, int)" % (argument_var,)
  
          def input_conversion(self, cpp_type, argument_var, arg_num):
              code = ""
              # here we inject special behavoir for testing if this converter
              # was called !
              call_as = "(1 + <int>%s)" % argument_var
              cleanup = ""
              return code, call_as, cleanup
  
          def output_conversion(self, cpp_type, input_cpp_var, output_py_var):
              return "%s = <int>%s" % (output_py_var, input_cpp_var)
  
      special_converters.append(SpecialIntConverter())
  
      target = os.path.join(test_files, "minimal_wrapper.pyx")
      include_dirs = autowrap.parse_and_generate_code(["minimal.pxd",
                                                       "minimal_td.pxd"],
                                                      root=test_files, target=target,  debug=True)
      cpp_source = os.path.join(test_files, "minimal.cpp")
      wrapped = autowrap.Utils.compile_and_import("wrapped", [target, cpp_source],
                                                  include_dirs)
      os.remove(target)
      assert wrapped.__name__ == "wrapped"
  
      minimal = wrapped.Minimal()
  
      assert len(minimal.compute.__doc__) == 297
  
      assert len(minimal.run.__doc__) == 111
  
      # test members
      assert minimal.m_accessible == 0
      assert minimal.m_const == -1
  
      minimal.m_accessible = 10
      assert minimal.m_accessible == 10
  
      try:
          minimal.m_const = 10
          assert False
      except AttributeError:
          # That is what we expected, cant modify a const member
          pass
  
  
      assert minimal.compute(3) == 4
      # overloaded for float:
      assert minimal.compute(0.0) == 42.0
  
      assert minimal.compute(1, 2) == 3
      assert minimal.compute_int(4) == 5
      assert minimal.compute(b"uwe") == b'ewu'
      assert minimal.compute_str(b"emzed") == b"dezme"
      assert minimal.pass_charptr(b"emzed") == b"emzed"
      assert minimal.pass_const_charptr(b"emzed") == b"emzed"
  
      assert minimal.compute_int() == 42
  
      # the c++ code of test_special_converter returns the same value, but
      # our special converter above modifies the function, so:
      assert minimal.test_special_converter(0) == 1
  
      expect_exception(lambda: minimal.compute(None))()
  
      assert minimal.compute_charp(b"uwe") == 3
  
      assert minimal.run(minimal) == 4
      assert minimal.run2(minimal) == 5
  
      # Note that both C++ calls run3 and run4 do modify the object -- the fact
      # that Cython thinks run4 is const does not impact this!
      tm = wrapped.Minimal(5)
      assert tm.get() == 5
      assert tm.run3(tm) == 14
      assert tm.get() == 10
      assert tm.run3(tm) == 24
      assert tm.get() == 20
      tm = wrapped.Minimal(5)
      assert tm.run4(tm) == 14
      assert tm.get() == 10
      assert tm.run4(tm) == 24
      assert tm.get() == 20
  
      assert minimal.create().compute(3) == 4
  
      assert minimal.sumup([1, 2, 3]) == 6
  
      m2 = wrapped.Minimal(-1)
      assert m2.compute(3) == 3
  
      assert wrapped.Minimal.ABCorD.A == 0
      assert wrapped.Minimal.ABCorD.B == 2
      assert wrapped.Minimal.ABCorD.C == 3
      assert wrapped.Minimal.ABCorD.D == 4
  
      in_ = [m2, minimal]
  
      m3 = copy.copy(m2)
      assert m3 == m2
  
      m3 = wrapped.Minimal([1, 2, 3])
      assert m3.compute(0) == 4
  
      ### Different ways of wrapping a function: 
      # all three call() methods (call, call2, call3) do exactly the same thing
      # and all modify the input argument. However, they are wrapped differently
      # in the pxd file:
      #
      #   int call(libcpp_vector[Minimal] what) # ref-arg-out:0
      #   int call2(libcpp_vector[Minimal]& what) # ref-arg-out:0
      #   int call3(const libcpp_vector[Minimal]& what) # ref-arg-out:0
      #
      # and therefore only call2 will actually modify its input arguments (since
      # call assumes call by value, call3 assumes call by const-ref and only
      # call2 implements a full call by ref).
      #
      assert len(in_) == 2
      assert m3.call(in_) == 1
      assert len(in_) == 2
      assert in_ == [m2, minimal]
  
      assert len(in_) == 2
      assert m3.call3(in_) == 1
      assert len(in_) == 2
      assert in_ == [m2, minimal]
  
      assert len(in_) == 2
      assert m3.call2(in_) == 1
      assert len(in_) == 3
      assert in_ == [m2, minimal, m2]
  
      in_ = [b"a", b"bc"]
      assert m3.call_str(in_) == 3
      assert in_ == [b"a", b"bc", b"hi"]
  
      msg, = m3.message()
      assert msg == b"hello"
  
      m1, m2 = m3.create_two()
      assert m1.compute(42) == 42
      assert m2.compute(42) == 43
  
      assert m2.enumTest(wrapped.Minimal.ABCorD.A) == wrapped.Minimal.ABCorD.A
  
      expect_exception(lambda: m2.enumTest(1))()
  
      m2.setVector([m2, m1, m3])
      a, b, c = m2.getVector()
      assert a == m2
      assert b == m1
      assert c == m3
  
      a, b, c = list(m2)  # call __iter__
      assert a == m2
      assert b == m1
      assert c == m3
  
      assert m2.test2Lists([m1], [1, 2]) == 3
      assert m1 == m1
  
      # tests operator[] + size:
      assert list(m1) == []
      assert list(m2) == [m2, m1, m3]
  
      assert wrapped.top_function(42) == 84
      assert wrapped.sumup([1, 2, 3]) == 6
      assert wrapped.Minimal.run_static(1) == 4
      assert wrapped.Minimal.run_static_extra_arg(1, True) == 4
  
      # != not declared, so:
      expect_exception(lambda m1, m2: m1 != m2)(m1, m2)
  
      assert m1.toInt() == 4711
  
      assert m2[0] == 1
      assert m2[1] == 2
      assert m2[2] == 3
  
      # Was OverflowError, but now we check positivity for unsigned ints
      with pytest.raises(AssertionError):
          m2[-1]
  
      with pytest.raises(IndexError):
          m2[3]
  
      # operator add
      assert wrapped.Minimal(1) + wrapped.Minimal(2) == wrapped.Minimal(3)
  
      m1 = wrapped.Minimal(1)
      m1 += m1
      assert m1 == wrapped.Minimal(2)
  
      m1 = wrapped.Minimal(1)
      m1 = m1 + m1
      assert m1 == wrapped.Minimal(2)
  
      # operator sub
      assert wrapped.Minimal(5) - wrapped.Minimal(2) == wrapped.Minimal(3)
  
      m1 = wrapped.Minimal(1)
      m1 -= m1
      assert m1 == wrapped.Minimal(0)
  
      # operator mult
      assert wrapped.Minimal(5) * wrapped.Minimal(2) == wrapped.Minimal(10)
  
      m1 = wrapped.Minimal(3)
      m1 *= m1
      m2 = m1 * m1
      assert m1 == wrapped.Minimal(9)
      assert m2 == wrapped.Minimal(81)
  
      # operator div
      assert wrapped.Minimal(10) / wrapped.Minimal(2) == wrapped.Minimal(5)
  
      m1 = wrapped.Minimal(3)
      m1 /= m1
      assert m1 == wrapped.Minimal(1)
  
  
  