test_assertions.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests assertion methods.
  4. """
  5. import os
  6. import grass.script.core as gcore
  7. from grass.pygrass.modules import Module
  8. from grass.gunittest.case import TestCase
  9. from grass.gunittest.main import test
  10. from grass.gunittest.gmodules import SimpleModule
  11. class TestTextAssertions(TestCase):
  12. # pylint: disable=R0904
  13. std_newline = "aaa\nbbb\n"
  14. platfrom_newline = "aaa{nl}bbb{nl}".format(nl=os.linesep)
  15. def test_assertLooksLike(self):
  16. self.assertLooksLike("Generated map is <elevation>",
  17. "Generated map is <...>")
  18. self.assertRaises(self.failureException,
  19. self.assertLooksLike,
  20. "Generated map is elevation.",
  21. "Generated map is <...>")
  22. self.assertLooksLike("Projection string: '+proj=longlat +datum=WGS84'",
  23. "Projection string: ...")
  24. def test_assertLooksLike_multiline(self):
  25. self.assertLooksLike("a=123\nb=456\nc=789",
  26. "a=...\nb=...\nc=...")
  27. def test_assertLooksLike_multiline_platform_dependent(self):
  28. self.assertLooksLike("a=123\nb=456\nc=789",
  29. "a=...{nl}b=...{nl}c=...".format(nl=os.linesep))
  30. def test_assertLooksLike_numbers(self):
  31. self.assertLooksLike("abc = 125521",
  32. "abc = 125...")
  33. self.assertLooksLike("abc = 689.156",
  34. "abc = 689...")
  35. self.assertLooksLike("abc = 689.159589",
  36. "abc = 689.15...")
  37. # this should fail according to the implementation
  38. # first three dots are considered as ellipses
  39. self.assertRaises(self.failureException,
  40. self.assertLooksLike,
  41. "abc = 689.159589",
  42. "abc = 689....")
  43. def do_all_combidnations(self, first, second, function):
  44. function(first, first)
  45. function(first, second)
  46. function(second, first)
  47. function(second, second)
  48. def test_assertMultiLineEqual(self):
  49. r"""Test different combinations of ``\n`` and os.linesep"""
  50. self.do_all_combidnations(self.std_newline, self.platfrom_newline,
  51. function=self.assertMultiLineEqual)
  52. def test_assertMultiLineEqual_raises(self):
  53. """Test mixed line endings"""
  54. self.assertRaises(self.failureException,
  55. self.assertMultiLineEqual,
  56. "aaa\n\rbbb\r",
  57. "aaa\nbbb\n")
  58. def test_assertEqual(self):
  59. """Test for of newlines for strings (uses overwritten assertMultiLineEqual())"""
  60. self.do_all_combidnations(self.std_newline, self.platfrom_newline,
  61. function=self.assertEqual)
  62. def test_assertEqual_raises(self):
  63. """Test mixed line endings"""
  64. self.assertRaises(self.failureException,
  65. self.assertEqual,
  66. "aaa\n\rbbb\r",
  67. "aaa\nbbb\n")
  68. R_UNIVAR_ELEVATION_SUBSET = """n=2025000
  69. null_cells=0
  70. min=55.5787925720215
  71. max=156.329864501953
  72. """
  73. RANDOM_KEYVALUES = """abc=2025000
  74. aaa=55.5787925720215
  75. bbb=156.329864501953
  76. """
  77. R_INFO_ELEVATION_SUBSET = """rows=1350
  78. cols=1500
  79. cells=2025000
  80. datatype=FCELL
  81. """
  82. # r.info -gre map=elevation
  83. ELEVATION_MAPSET_DICT = {'mapset': 'PERMANENT'}
  84. # r.univar map=elevation
  85. ELEVATION_MINMAX = """min=55.5787925720215
  86. max=156.329864501953
  87. """
  88. # values rounded manually to maximal expected perecision
  89. ELEVATION_MINMAX_DICT = {'min': 55.58, 'max': 156.33}
  90. class TestAssertModuleKeyValue(TestCase):
  91. """Test usage of `assertModuleKeyValue` method."""
  92. # pylint: disable=R0904
  93. @classmethod
  94. def setUpClass(cls):
  95. cls.use_temp_region()
  96. cls.runModule(SimpleModule('g.region', raster='elevation'))
  97. @classmethod
  98. def tearDownClass(cls):
  99. cls.del_temp_region()
  100. def test_pygrass_module(self):
  101. """Test syntax with Module and required parameters as module"""
  102. module = Module('r.info', map='elevation', flags='gr',
  103. run_=False, finish_=True)
  104. self.assertModuleKeyValue(module,
  105. reference=dict(min=55.58, max=156.33),
  106. precision=0.01, sep='=')
  107. def test_pygrass_simple_module(self):
  108. """Test syntax with SimpleModule as module"""
  109. module = SimpleModule('r.info', map='elevation', flags='gr')
  110. self.assertModuleKeyValue(module,
  111. reference=dict(min=55.58, max=156.33),
  112. precision=0.01, sep='=')
  113. def test_direct_parameters(self):
  114. """Test syntax with module and its parameters as function parameters"""
  115. self.assertModuleKeyValue('r.info', map='elevation', flags='gr',
  116. reference=dict(min=55.58, max=156.33),
  117. precision=0.01, sep='=')
  118. def test_parameters_parameter(self):
  119. """Test syntax with module parameters in one parameters dictionary"""
  120. self.assertModuleKeyValue(module='r.info',
  121. parameters=dict(map='elevation', flags='gr'),
  122. reference=dict(min=55.58, max=156.33),
  123. precision=0.01, sep='=')
  124. class TestRasterMapAssertions(TestCase):
  125. # pylint: disable=R0904
  126. @classmethod
  127. def setUpClass(cls):
  128. cls.use_temp_region()
  129. # TODO: here we should actually not call self.runModule but call_module
  130. cls.runModule(SimpleModule('g.region', raster='elevation'))
  131. @classmethod
  132. def tearDownClass(cls):
  133. cls.del_temp_region()
  134. def test_assertRasterFitsUnivar(self):
  135. self.assertRasterFitsUnivar('elevation', R_UNIVAR_ELEVATION_SUBSET,
  136. precision=0.01)
  137. self.assertRaises(self.failureException,
  138. self.assertRasterFitsUnivar,
  139. 'geology', R_UNIVAR_ELEVATION_SUBSET, precision=0.01)
  140. self.assertRaises(ValueError,
  141. self.assertRasterFitsUnivar,
  142. 'elevation', RANDOM_KEYVALUES)
  143. def test_assertRasterFitsInfo(self):
  144. self.assertRasterFitsInfo('elevation', R_INFO_ELEVATION_SUBSET)
  145. self.assertRaises(self.failureException,
  146. self.assertRasterFitsInfo,
  147. 'geology', R_INFO_ELEVATION_SUBSET)
  148. self.assertRaises(ValueError,
  149. self.assertRasterFitsInfo,
  150. 'elevation', RANDOM_KEYVALUES)
  151. def test_common_values_info_univar(self):
  152. self.assertRasterFitsUnivar('elevation',
  153. ELEVATION_MINMAX, precision=0.01)
  154. self.assertRasterFitsInfo('elevation',
  155. ELEVATION_MINMAX, precision=0.01)
  156. def test_dict_as_parameter(self):
  157. """This also tests if we are using r.info -e flag and that precision is
  158. not required for strings.
  159. """
  160. self.assertRasterFitsInfo('elevation', ELEVATION_MAPSET_DICT)
  161. def test_assertRastersNoDifference(self):
  162. """Test basic usage of assertRastersNoDifference"""
  163. self.assertRastersNoDifference(actual='elevation',
  164. reference='elevation',
  165. precision=0, # this might need to be increased
  166. msg="The same maps should have no difference")
  167. self.assertRaises(self.failureException,
  168. self.assertRastersNoDifference,
  169. actual='elevation',
  170. reference='geology',
  171. precision=1,
  172. msg="Different maps should have difference")
  173. def test_assertRastersNoDifference_mean(self):
  174. """Test usage of assertRastersNoDifference with mean"""
  175. self.assertRastersNoDifference(actual='elevation',
  176. reference='elevation',
  177. precision=0, # this might need to be increased
  178. statistics=dict(mean=0),
  179. msg="The difference of same maps should have small mean")
  180. self.assertRaises(self.failureException,
  181. self.assertRastersNoDifference,
  182. actual='elevation',
  183. reference='geology',
  184. precision=1,
  185. statistics=dict(mean=0),
  186. msg="The difference of different maps should have huge mean")
  187. class TestMapExistsAssertions(TestCase):
  188. # pylint: disable=R0904
  189. raster_cell = 'TestMapExistsAssertions_raster_cell'
  190. raster_dcell = 'TestMapExistsAssertions_raster_dcell'
  191. raster3d = 'TestMapExistsAssertions_raster3D'
  192. vector = 'TestMapExistsAssertions_vector'
  193. @classmethod
  194. def setUpClass(cls):
  195. cls.use_temp_region()
  196. cls.runModule('g.region', n=10, e=10, s=0, w=0, t=10, b=0, res=1)
  197. cls.runModule('r.mapcalc', expression=cls.raster_cell + ' = 1')
  198. cls.runModule('r.mapcalc', expression=cls.raster_dcell + ' = 1.0')
  199. cls.runModule('r3.mapcalc', expression=cls.raster3d + ' = 1.0')
  200. cls.runModule('v.edit', map=cls.vector, tool='create')
  201. @classmethod
  202. def tearDownClass(cls):
  203. cls.runModule('g.remove', flags='f',
  204. type=['raster', 'raster3d', 'vector'],
  205. name=[cls.raster_cell, cls.raster_dcell,
  206. cls.raster3d, cls.vector])
  207. cls.del_temp_region()
  208. def test_rast_cell_exists(self):
  209. self.assertRasterExists(self.raster_cell)
  210. def test_rast_dcell_exists(self):
  211. self.assertRasterExists(self.raster_dcell)
  212. def test_rast_does_not_exist(self):
  213. self.assertRaises(self.failureException,
  214. self.assertRasterExists,
  215. 'does_not_exists')
  216. def test_rast3d_exists(self):
  217. self.assertRaster3dExists(self.raster3d)
  218. def test_rast3d_does_not_exist(self):
  219. self.assertRaises(self.failureException,
  220. self.assertRaster3dExists,
  221. 'does_not_exists')
  222. def test_vect_exists(self):
  223. self.assertVectorExists(self.vector)
  224. def test_vect_does_not_exist(self):
  225. self.assertRaises(self.failureException,
  226. self.assertVectorExists,
  227. 'does_not_exists')
  228. def test_rast_does_not_exist_in_current_mapset(self):
  229. # expecting that there is elevation in PERMANENT
  230. # TODO: use skip decorator
  231. # TODO: add the same tests but for vect and rast3d
  232. self.assertRaises(self.failureException,
  233. self.assertRasterExists,
  234. 'elevation',
  235. msg="Rasters from different mapsets should be ignored")
  236. class TestFileAssertions(TestCase):
  237. # pylint: disable=R0904
  238. @classmethod
  239. def setUpClass(cls):
  240. # we expect WIND to be always present
  241. gisenv = gcore.gisenv()
  242. cls.existing_file = os.path.join(gisenv['GISDBASE'],
  243. gisenv['LOCATION_NAME'],
  244. 'PERMANENT', 'WIND')
  245. cls.emtpy_file = cls.__name__ + '_this_is_an_empty_file'
  246. open(cls.emtpy_file, 'w').close()
  247. cls.file_with_md5 = cls.__name__ + '_this_is_a_file_with_known_md5'
  248. file_content = 'Content of the file with known MD5.\n'
  249. with open(cls.file_with_md5, 'w') as f:
  250. f.write(file_content)
  251. # MD5 sum created using:
  252. # echo 'Content of the file with known MD5.' > some_file.txt
  253. # md5sum some_file.txt
  254. cls.file_md5 = '807bba4ffac4bb351bc3f27853009949'
  255. cls.file_with_same_content = cls.__name__ + '_file_with_same_content'
  256. with open(cls.file_with_same_content, 'w') as f:
  257. f.write(file_content)
  258. cls.file_with_different_content = cls.__name__ + '_file_with_different_content'
  259. with open(cls.file_with_different_content, 'w') as f:
  260. f.write(file_content + ' Something else here.')
  261. @classmethod
  262. def tearDownClass(cls):
  263. os.remove(cls.emtpy_file)
  264. os.remove(cls.file_with_md5)
  265. os.remove(cls.file_with_same_content)
  266. os.remove(cls.file_with_different_content)
  267. def test_assertFileExists(self):
  268. self.assertFileExists(filename=self.existing_file)
  269. self.assertRaises(self.failureException,
  270. self.assertFileExists,
  271. filename='this_one_does_not_exists')
  272. def test_assertFileExists_empty_file(self):
  273. self.assertFileExists(filename=self.emtpy_file, skip_size_check=True)
  274. self.assertRaises(self.failureException,
  275. self.assertFileExists,
  276. filename=self.emtpy_file)
  277. def test_assertFileMd5(self):
  278. self.assertFileMd5(filename=self.file_with_md5, md5=self.file_md5)
  279. self.assertRaises(self.failureException,
  280. self.assertFileMd5,
  281. filename=self.file_with_md5, md5='wrongmd5')
  282. def test_assertFilesEqualMd5(self):
  283. self.assertFilesEqualMd5(filename=self.file_with_md5,
  284. reference=self.file_with_same_content)
  285. self.assertRaises(self.failureException,
  286. self.assertFilesEqualMd5,
  287. filename=self.file_with_md5,
  288. reference=self.file_with_different_content)
  289. if __name__ == '__main__':
  290. test()