diff --git a/modules/algebra/test/expensive_test_vectord_mismatch.py b/modules/algebra/test/expensive_test_vectord_mismatch.py new file mode 100644 index 0000000000..fade7d72d9 --- /dev/null +++ b/modules/algebra/test/expensive_test_vectord_mismatch.py @@ -0,0 +1,18 @@ +import IMP.test + + +class Tests(IMP.test.TestCase): + + def test_vectord_mismatch(self): + """Test combination of VectorD of different dimensions""" + # Should be a compile-time error to combine VectorD of different sizes + self.assertCompileFails( + includes=['IMP/algebra/VectorD.h'], + body=""" +IMP::algebra::Vector3D v1(1,2,3); +IMP::algebra::Vector4D v3(7,8,9,10); +v1 -= v3;""") + + +if __name__ == '__main__': + IMP.test.main() diff --git a/modules/kernel/test/expensive_test_get_array.py b/modules/kernel/test/expensive_test_get_array.py new file mode 100644 index 0000000000..99d2b72f3c --- /dev/null +++ b/modules/kernel/test/expensive_test_get_array.py @@ -0,0 +1,17 @@ +import IMP.test + + +class Tests(IMP.test.TestCase): + + def test_get_array(self): + """Test std::get""" + # Should be a compile-time error to access an out of range element + self.assertCompileFails( + includes=['IMP/base_types.h'], + body=""" +IMP::ParticleIndexPair pp(IMP::ParticleIndex(1), IMP::ParticleIndex(3)); +IMP::ParticleIndex p = std::get<2>(pp);""") + + +if __name__ == '__main__': + IMP.test.main() diff --git a/modules/test/pyext/src/__init__.py b/modules/test/pyext/src/__init__.py index c6d991211c..023828e913 100644 --- a/modules/test/pyext/src/__init__.py +++ b/modules/test/pyext/src/__init__.py @@ -318,6 +318,42 @@ def assertSequenceAlmostEqual(self, first, second, places=None, msg=None, msg = self._formatMessage(msg, standardMsg) raise self.failureException(msg) + def _read_cmake_cache(self, cmake_cache): + """Parse CMakeCache and extract info on the C++ compiler""" + cxx = flags = None + with open(cmake_cache) as fh: + for line in fh: + if line.startswith('CMAKE_CXX_COMPILER:'): + cxx = line.split('=', 1)[1].rstrip('\r\n') + elif line.startswith('CMAKE_CXX_FLAGS:'): + flags = line.split('=', 1)[1].rstrip('\r\n') + return cxx, flags + + def assertCompileFails(self, includes, body): + """Test that the given C++ code fails to compile with a static + assertion.""" + libdir = os.path.dirname(IMP.__file__) + cmake_cache = os.path.join(libdir, '..', '..', 'CMakeCache.txt') + include = os.path.join(libdir, '..', '..', 'include') + if not os.path.exists(cmake_cache): + self.skipTest("cannot find CMakeCache.txt") + cxx, flags = self._read_cmake_cache(cmake_cache) + with temporary_directory() as tmpdir: + fname = os.path.join(tmpdir, 'test.cpp') + with open(fname, 'w') as fh: + for inc in includes: + fh.write("#include <%s>\n" % inc) + fh.write("\nint main() {\n" + body + "\n return 0;\n}\n") + cmdline = "%s %s -I%s %s" % (cxx, flags, include, fname) + print(cmdline) + p = subprocess.Popen(cmdline, shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + out, err = p.communicate() + self.assertIn('error: static assertion failed', err) + + def create_point_particle(self, model, x, y, z): """Make a particle with optimizable x, y and z attributes, and add it to the model."""