collection of python libs developed for testing purposes

test_hoover.py 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. #!/usr/bin/python
  2. # flake8: noqa
  3. import unittest
  4. from sznqalibs import hoover
  5. import copy
  6. import json
  7. import unittest
  8. class DictPathTest(unittest.TestCase):
  9. def setUp(self):
  10. super(DictPathTest, self).setUp()
  11. class PathyDict(dict, hoover.DictPath):
  12. pass
  13. testDict = {
  14. 's': 11,
  15. 'x': {
  16. 'a': 55,
  17. 'hello': {
  18. 'world': 1, 'sun': 3, 'blackhole': None
  19. },
  20. 'b': 59
  21. },
  22. }
  23. self.pdict = PathyDict(testDict)
  24. def testDelSun(self):
  25. oracle = copy.deepcopy(self.pdict)
  26. result = copy.deepcopy(self.pdict)
  27. del oracle['x']['hello']['sun']
  28. result.delpath("/x/hello/sun")
  29. self.assertEqual(oracle, result)
  30. def testGetHello(self):
  31. oracle = copy.deepcopy(self.pdict['x']['hello'])
  32. result = self.pdict.getpath("/x/hello")
  33. self.assertEqual(oracle, result)
  34. def testSetHello(self):
  35. oracle = copy.deepcopy(self.pdict)
  36. result = copy.deepcopy(self.pdict)
  37. oracle['x']['hello']['sun'] = 'moon'
  38. result.setpath("/x/hello/sun", 'moon')
  39. self.assertEqual(oracle, result)
  40. def testSetNewItem(self):
  41. oracle = copy.deepcopy(self.pdict)
  42. result = copy.deepcopy(self.pdict)
  43. oracle['x']['hullo'] = 'NEW'
  44. result.setpath("/x/hullo", 'NEW')
  45. self.assertEqual(oracle, result)
  46. def testHelloExists(self):
  47. self.assertTrue(self.pdict.ispath('/x/hello'))
  48. def testWorldNotExists(self):
  49. self.assertFalse(self.pdict.ispath('/x/world'))
  50. def testDelBadPath(self):
  51. fn = lambda: self.pdict.delpath('/x/hullo')
  52. self.assertRaises(KeyError, fn)
  53. def testGetBadPath(self):
  54. fn = lambda: self.pdict.getpath('/x/hullo')
  55. self.assertRaises(KeyError, fn)
  56. def testSetBadPath(self):
  57. fn = lambda: self.pdict.setpath('/x/hullo/newthing', 1)
  58. self.assertRaises(KeyError, fn)
  59. # the scary None
  60. def testDelNone(self):
  61. oracle = copy.deepcopy(self.pdict)
  62. result = copy.deepcopy(self.pdict)
  63. del oracle['x']['hello']['blackhole']
  64. result.delpath("/x/hello/blackhole")
  65. self.assertEqual(oracle, result)
  66. def testSetNone(self):
  67. oracle = copy.deepcopy(self.pdict)
  68. result = copy.deepcopy(self.pdict)
  69. oracle['x']['hello']['sun'] = None
  70. result.setpath("/x/hello/sun", None)
  71. self.assertEqual(oracle, result)
  72. def testSetNewNone(self):
  73. oracle = copy.deepcopy(self.pdict)
  74. result = copy.deepcopy(self.pdict)
  75. oracle['x']['hullo'] = None
  76. result.setpath("/x/hullo", None)
  77. self.assertEqual(oracle, result)
  78. def testGetNone(self):
  79. oracle = copy.deepcopy(self.pdict['x']['hello']['blackhole'])
  80. result = self.pdict.getpath("/x/hello/blackhole")
  81. self.assertEqual(oracle, result)
  82. def testNoneExists(self):
  83. result = self.pdict.ispath('/x/hello/blackhole')
  84. self.assertTrue(result)
  85. class CartmanTest(unittest.TestCase):
  86. def sdiff(self, a, b):
  87. sa = [json.dumps(i) for i in a]
  88. sb = [json.dumps(i) for i in b]
  89. diff = set(sa) - set(sb)
  90. return [json.loads(i) for i in diff]
  91. def chkoracle(self, o):
  92. def dups(self):
  93. so = [json.dumps(i) for i in o]
  94. return len(o) != len(set(so))
  95. if dups(o):
  96. self.logger.warn("duplicates in oracle!")
  97. def setUp(self):
  98. super(CartmanTest, self).setUp()
  99. def compare(self, source, scheme, oracle):
  100. self.chkoracle(oracle)
  101. def fmtdiff(diff, word):
  102. strn = ""
  103. if diff:
  104. strn = ("\n----------------------"
  105. "\n %s elements (%s):\n%s"
  106. % (word, len(diff), pretty(diff)))
  107. return strn
  108. pretty = hoover.jsDump
  109. cm = hoover.Cartman(source, scheme)
  110. result = [i for i in cm]
  111. xtra = self.sdiff(result, oracle)
  112. miss = self.sdiff(oracle, result)
  113. err = ""
  114. err += fmtdiff(miss, 'missing')
  115. err += fmtdiff(xtra, 'extra')
  116. return err
  117. def test_Flat_2of3(self):
  118. scheme = {
  119. 'a': hoover.Cartman.Iterable,
  120. 'b': hoover.Cartman.Iterable,
  121. }
  122. source = {
  123. 'a': [1, 2, 3],
  124. 'b': ['i', 'ii', 'iii'],
  125. 'c': ['I', 'II', 'III'],
  126. }
  127. oracle = [
  128. {'a': 1, 'b': 'i'},
  129. {'a': 1, 'b': 'ii'},
  130. {'a': 1, 'b': 'iii'},
  131. {'a': 2, 'b': 'i'},
  132. {'a': 2, 'b': 'ii'},
  133. {'a': 2, 'b': 'iii'},
  134. {'a': 3, 'b': 'i'},
  135. {'a': 3, 'b': 'ii'},
  136. {'a': 3, 'b': 'iii'},
  137. ]
  138. err = self.compare(source, scheme, oracle)
  139. self.assertFalse(err, "errors found: %s\n" % err)
  140. def test_Deep1(self):
  141. scheme = {
  142. 'a': hoover.Cartman.Iterable,
  143. 'b': hoover.Cartman.Iterable,
  144. 'x': {
  145. 'h1': hoover.Cartman.Iterable,
  146. 'h2': hoover.Cartman.Iterable,
  147. }
  148. }
  149. source = {
  150. 'a': [1, 2, 3],
  151. 'b': ['i', 'ii', 'iii'],
  152. 'x': {'h1': [101, 102], 'h2': [201, 202]}
  153. }
  154. oracle = [
  155. {'a': 1, 'b': 'i', 'x': {'h1': 101, 'h2': 201}},
  156. {'a': 1, 'b': 'i', 'x': {'h1': 101, 'h2': 202}},
  157. {'a': 1, 'b': 'i', 'x': {'h1': 102, 'h2': 201}},
  158. {'a': 1, 'b': 'i', 'x': {'h1': 102, 'h2': 202}},
  159. {'a': 1, 'b': 'ii', 'x': {'h1': 101, 'h2': 201}},
  160. {'a': 1, 'b': 'ii', 'x': {'h1': 101, 'h2': 202}},
  161. {'a': 1, 'b': 'ii', 'x': {'h1': 102, 'h2': 201}},
  162. {'a': 1, 'b': 'ii', 'x': {'h1': 102, 'h2': 202}},
  163. {'a': 1, 'b': 'iii', 'x': {'h1': 101, 'h2': 201}},
  164. {'a': 1, 'b': 'iii', 'x': {'h1': 101, 'h2': 202}},
  165. {'a': 1, 'b': 'iii', 'x': {'h1': 102, 'h2': 201}},
  166. {'a': 1, 'b': 'iii', 'x': {'h1': 102, 'h2': 202}},
  167. {'a': 2, 'b': 'i', 'x': {'h1': 101, 'h2': 201}},
  168. {'a': 2, 'b': 'i', 'x': {'h1': 101, 'h2': 202}},
  169. {'a': 2, 'b': 'i', 'x': {'h1': 102, 'h2': 201}},
  170. {'a': 2, 'b': 'i', 'x': {'h1': 102, 'h2': 202}},
  171. {'a': 2, 'b': 'ii', 'x': {'h1': 101, 'h2': 201}},
  172. {'a': 2, 'b': 'ii', 'x': {'h1': 101, 'h2': 202}},
  173. {'a': 2, 'b': 'ii', 'x': {'h1': 102, 'h2': 201}},
  174. {'a': 2, 'b': 'ii', 'x': {'h1': 102, 'h2': 202}},
  175. {'a': 2, 'b': 'iii', 'x': {'h1': 101, 'h2': 201}},
  176. {'a': 2, 'b': 'iii', 'x': {'h1': 101, 'h2': 202}},
  177. {'a': 2, 'b': 'iii', 'x': {'h1': 102, 'h2': 201}},
  178. {'a': 2, 'b': 'iii', 'x': {'h1': 102, 'h2': 202}},
  179. {'a': 3, 'b': 'i', 'x': {'h1': 101, 'h2': 201}},
  180. {'a': 3, 'b': 'i', 'x': {'h1': 101, 'h2': 202}},
  181. {'a': 3, 'b': 'i', 'x': {'h1': 102, 'h2': 201}},
  182. {'a': 3, 'b': 'i', 'x': {'h1': 102, 'h2': 202}},
  183. {'a': 3, 'b': 'ii', 'x': {'h1': 101, 'h2': 201}},
  184. {'a': 3, 'b': 'ii', 'x': {'h1': 101, 'h2': 202}},
  185. {'a': 3, 'b': 'ii', 'x': {'h1': 102, 'h2': 201}},
  186. {'a': 3, 'b': 'ii', 'x': {'h1': 102, 'h2': 202}},
  187. {'a': 3, 'b': 'iii', 'x': {'h1': 101, 'h2': 201}},
  188. {'a': 3, 'b': 'iii', 'x': {'h1': 101, 'h2': 202}},
  189. {'a': 3, 'b': 'iii', 'x': {'h1': 102, 'h2': 201}},
  190. {'a': 3, 'b': 'iii', 'x': {'h1': 102, 'h2': 202}},
  191. ]
  192. err = self.compare(source, scheme, oracle)
  193. self.assertFalse(err, "errors found: %s\n" % err)
  194. def test_Scalar(self):
  195. scheme = {
  196. 'a': hoover.Cartman.Iterable,
  197. 'b': hoover.Cartman.Iterable,
  198. 'il': hoover.Cartman.Scalar,
  199. 'id': hoover.Cartman.Scalar,
  200. 'ii': hoover.Cartman.Scalar,
  201. }
  202. source = {
  203. 'a': [1, 2, 3],
  204. 'b': ['i', 'ii', 'iii'],
  205. 'il': [2, 7],
  206. 'id': {'a': 1},
  207. 'ii': 42
  208. }
  209. invars = {
  210. 'il': [2, 7], 'id': {'a': 1}, 'ii': 42
  211. }
  212. oracle = [
  213. {'a': 1, 'b': 'i'},
  214. {'a': 1, 'b': 'ii'},
  215. {'a': 1, 'b': 'iii'},
  216. {'a': 2, 'b': 'i'},
  217. {'a': 2, 'b': 'ii'},
  218. {'a': 2, 'b': 'iii'},
  219. {'a': 3, 'b': 'i'},
  220. {'a': 3, 'b': 'ii'},
  221. {'a': 3, 'b': 'iii'},
  222. ]
  223. for o in oracle:
  224. o.update(invars)
  225. err = self.compare(source, scheme, oracle)
  226. self.assertFalse(err, "errors found: %s\n" % err)
  227. def test_dataDangling(self):
  228. scheme = {
  229. 'a': hoover.Cartman.Iterable,
  230. 'b': hoover.Cartman.Iterable,
  231. }
  232. source = {
  233. 'a': [1, 2, 3],
  234. 'b': ['i', 'ii', 'iii'],
  235. 'dangling_str': "tr",
  236. 'dangling_dict': {'a': 1},
  237. 'dangling_list': []
  238. }
  239. oracle = [
  240. {'a': 1, 'b': 'i'},
  241. {'a': 1, 'b': 'ii'},
  242. {'a': 1, 'b': 'iii'},
  243. {'a': 2, 'b': 'i'},
  244. {'a': 2, 'b': 'ii'},
  245. {'a': 2, 'b': 'iii'},
  246. {'a': 3, 'b': 'i'},
  247. {'a': 3, 'b': 'ii'},
  248. {'a': 3, 'b': 'iii'},
  249. ]
  250. err = self.compare(source, scheme, oracle)
  251. self.assertFalse(err, "errors found: %s\n" % err)
  252. def test_dataMissing(self):
  253. scheme = {
  254. 'a': hoover.Cartman.Iterable,
  255. 'b': hoover.Cartman.Iterable,
  256. 'MIA': hoover.Cartman.Iterable,
  257. }
  258. source = {
  259. 'a': [1, 2, 3],
  260. 'b': ['i', 'ii', 'iii'],
  261. }
  262. oracle = [
  263. {'a': 1, 'b': 'i'},
  264. {'a': 1, 'b': 'ii'},
  265. {'a': 1, 'b': 'iii'},
  266. {'a': 2, 'b': 'i'},
  267. {'a': 2, 'b': 'ii'},
  268. {'a': 2, 'b': 'iii'},
  269. {'a': 3, 'b': 'i'},
  270. {'a': 3, 'b': 'ii'},
  271. {'a': 3, 'b': 'iii'},
  272. ]
  273. err = self.compare(source, scheme, oracle)
  274. self.assertFalse(err, "errors found: %s\n" % err)
  275. def test_withListIterator(self):
  276. scheme = {
  277. 'a': hoover.Cartman.Iterable,
  278. 'b': hoover.Cartman.Iterable,
  279. 'ITER': hoover.Cartman.Iterable,
  280. }
  281. source = {
  282. 'a': [1, 2, 3],
  283. 'b': ['i', 'ii', 'iii'],
  284. 'ITER': iter(['iterate', 'over', 'me'])
  285. }
  286. oracle = [
  287. {'a': 1, 'b': 'i', 'ITER': 'iterate'},
  288. {'a': 1, 'b': 'ii', 'ITER': 'iterate'},
  289. {'a': 1, 'b': 'iii', 'ITER': 'iterate'},
  290. {'a': 2, 'b': 'i', 'ITER': 'iterate'},
  291. {'a': 2, 'b': 'ii', 'ITER': 'iterate'},
  292. {'a': 2, 'b': 'iii', 'ITER': 'iterate'},
  293. {'a': 3, 'b': 'i', 'ITER': 'iterate'},
  294. {'a': 3, 'b': 'ii', 'ITER': 'iterate'},
  295. {'a': 3, 'b': 'iii', 'ITER': 'iterate'},
  296. {'a': 1, 'b': 'i', 'ITER': 'over'},
  297. {'a': 1, 'b': 'ii', 'ITER': 'over'},
  298. {'a': 1, 'b': 'iii', 'ITER': 'over'},
  299. {'a': 2, 'b': 'i', 'ITER': 'over'},
  300. {'a': 2, 'b': 'ii', 'ITER': 'over'},
  301. {'a': 2, 'b': 'iii', 'ITER': 'over'},
  302. {'a': 3, 'b': 'i', 'ITER': 'over'},
  303. {'a': 3, 'b': 'ii', 'ITER': 'over'},
  304. {'a': 3, 'b': 'iii', 'ITER': 'over'},
  305. {'a': 1, 'b': 'i', 'ITER': 'me'},
  306. {'a': 1, 'b': 'ii', 'ITER': 'me'},
  307. {'a': 1, 'b': 'iii', 'ITER': 'me'},
  308. {'a': 2, 'b': 'i', 'ITER': 'me'},
  309. {'a': 2, 'b': 'ii', 'ITER': 'me'},
  310. {'a': 2, 'b': 'iii', 'ITER': 'me'},
  311. {'a': 3, 'b': 'i', 'ITER': 'me'},
  312. {'a': 3, 'b': 'ii', 'ITER': 'me'},
  313. {'a': 3, 'b': 'iii', 'ITER': 'me'},
  314. ]
  315. err = self.compare(source, scheme, oracle)
  316. self.assertFalse(err, "errors found: %s\n" % err)
  317. def test_withCustomIterator_TypeA(self):
  318. class ITER_A:
  319. def __init__(self, items):
  320. self.items = items
  321. self.n = 0
  322. def __iter__(self):
  323. return self
  324. def __next__(self):
  325. try:
  326. item = self.items[self.n]
  327. except IndexError:
  328. raise StopIteration
  329. else:
  330. self.n += 1
  331. return item
  332. scheme = {
  333. 'd': {
  334. 'a': hoover.Cartman.Iterable,
  335. 'b': hoover.Cartman.Iterable,
  336. 'ITER_A': hoover.Cartman.Iterable
  337. }
  338. }
  339. source = {
  340. 'd': {
  341. 'a': [1, 2, 3],
  342. 'b': ['i', 'ii', 'iii'],
  343. 'ITER_A': ITER_A(['iterate', 'over', 'him'])
  344. }
  345. }
  346. oracle = [
  347. {'d': {'a': 1, 'b': 'i', 'ITER_A': 'iterate'}},
  348. {'d': {'a': 1, 'b': 'ii', 'ITER_A': 'iterate'}},
  349. {'d': {'a': 1, 'b': 'iii', 'ITER_A': 'iterate'}},
  350. {'d': {'a': 2, 'b': 'i', 'ITER_A': 'iterate'}},
  351. {'d': {'a': 2, 'b': 'ii', 'ITER_A': 'iterate'}},
  352. {'d': {'a': 2, 'b': 'iii', 'ITER_A': 'iterate'}},
  353. {'d': {'a': 3, 'b': 'i', 'ITER_A': 'iterate'}},
  354. {'d': {'a': 3, 'b': 'ii', 'ITER_A': 'iterate'}},
  355. {'d': {'a': 3, 'b': 'iii', 'ITER_A': 'iterate'}},
  356. {'d': {'a': 1, 'b': 'i', 'ITER_A': 'over'}},
  357. {'d': {'a': 1, 'b': 'ii', 'ITER_A': 'over'}},
  358. {'d': {'a': 1, 'b': 'iii', 'ITER_A': 'over'}},
  359. {'d': {'a': 2, 'b': 'i', 'ITER_A': 'over'}},
  360. {'d': {'a': 2, 'b': 'ii', 'ITER_A': 'over'}},
  361. {'d': {'a': 2, 'b': 'iii', 'ITER_A': 'over'}},
  362. {'d': {'a': 3, 'b': 'i', 'ITER_A': 'over'}},
  363. {'d': {'a': 3, 'b': 'ii', 'ITER_A': 'over'}},
  364. {'d': {'a': 3, 'b': 'iii', 'ITER_A': 'over'}},
  365. {'d': {'a': 1, 'b': 'i', 'ITER_A': 'him'}},
  366. {'d': {'a': 1, 'b': 'ii', 'ITER_A': 'him'}},
  367. {'d': {'a': 1, 'b': 'iii', 'ITER_A': 'him'}},
  368. {'d': {'a': 2, 'b': 'i', 'ITER_A': 'him'}},
  369. {'d': {'a': 2, 'b': 'ii', 'ITER_A': 'him'}},
  370. {'d': {'a': 2, 'b': 'iii', 'ITER_A': 'him'}},
  371. {'d': {'a': 3, 'b': 'i', 'ITER_A': 'him'}},
  372. {'d': {'a': 3, 'b': 'ii', 'ITER_A': 'him'}},
  373. {'d': {'a': 3, 'b': 'iii', 'ITER_A': 'him'}},
  374. ]
  375. err = self.compare(source, scheme, oracle)
  376. self.assertFalse(err, "errors found: %s\n" % err)
  377. def test_withCustomIterator_TypeB(self):
  378. class ITER_B:
  379. def __init__(self, items):
  380. self.items = items
  381. def __getitem__(self, n):
  382. return self.items[n]
  383. scheme = {
  384. 'd': {
  385. 'a': hoover.Cartman.Iterable,
  386. 'b': hoover.Cartman.Iterable,
  387. 'ITER_B': hoover.Cartman.Iterable
  388. }
  389. }
  390. source = {
  391. 'd': {
  392. 'a': [1, 2, 3],
  393. 'b': ['i', 'ii', 'iii'],
  394. 'ITER_B': ITER_B(['iterate', 'by', 'him'])
  395. }
  396. }
  397. oracle = [
  398. {'d': {'a': 1, 'b': 'i', 'ITER_B': 'iterate'}},
  399. {'d': {'a': 1, 'b': 'ii', 'ITER_B': 'iterate'}},
  400. {'d': {'a': 1, 'b': 'iii', 'ITER_B': 'iterate'}},
  401. {'d': {'a': 2, 'b': 'i', 'ITER_B': 'iterate'}},
  402. {'d': {'a': 2, 'b': 'ii', 'ITER_B': 'iterate'}},
  403. {'d': {'a': 2, 'b': 'iii', 'ITER_B': 'iterate'}},
  404. {'d': {'a': 3, 'b': 'i', 'ITER_B': 'iterate'}},
  405. {'d': {'a': 3, 'b': 'ii', 'ITER_B': 'iterate'}},
  406. {'d': {'a': 3, 'b': 'iii', 'ITER_B': 'iterate'}},
  407. {'d': {'a': 1, 'b': 'i', 'ITER_B': 'by'}},
  408. {'d': {'a': 1, 'b': 'ii', 'ITER_B': 'by'}},
  409. {'d': {'a': 1, 'b': 'iii', 'ITER_B': 'by'}},
  410. {'d': {'a': 2, 'b': 'i', 'ITER_B': 'by'}},
  411. {'d': {'a': 2, 'b': 'ii', 'ITER_B': 'by'}},
  412. {'d': {'a': 2, 'b': 'iii', 'ITER_B': 'by'}},
  413. {'d': {'a': 3, 'b': 'i', 'ITER_B': 'by'}},
  414. {'d': {'a': 3, 'b': 'ii', 'ITER_B': 'by'}},
  415. {'d': {'a': 3, 'b': 'iii', 'ITER_B': 'by'}},
  416. {'d': {'a': 1, 'b': 'i', 'ITER_B': 'him'}},
  417. {'d': {'a': 1, 'b': 'ii', 'ITER_B': 'him'}},
  418. {'d': {'a': 1, 'b': 'iii', 'ITER_B': 'him'}},
  419. {'d': {'a': 2, 'b': 'i', 'ITER_B': 'him'}},
  420. {'d': {'a': 2, 'b': 'ii', 'ITER_B': 'him'}},
  421. {'d': {'a': 2, 'b': 'iii', 'ITER_B': 'him'}},
  422. {'d': {'a': 3, 'b': 'i', 'ITER_B': 'him'}},
  423. {'d': {'a': 3, 'b': 'ii', 'ITER_B': 'him'}},
  424. {'d': {'a': 3, 'b': 'iii', 'ITER_B': 'him'}},
  425. ]
  426. err = self.compare(source, scheme, oracle)
  427. self.assertFalse(err, "errors found: %s\n" % err)
  428. def test_BadSchemeBelow(self):
  429. def fn():
  430. scheme = {
  431. 'h': 1,
  432. 'p': hoover.Cartman.Iterable,
  433. 'd': hoover.Cartman.Iterable
  434. }
  435. source = {
  436. 'h': {
  437. 'ua': ['ua1', 'ua2']
  438. },
  439. 'p': ['a', 'b'],
  440. 'd': [False, True]
  441. }
  442. next(iter(hoover.Cartman(source, scheme)))
  443. self.assertRaises(ValueError, fn)
  444. def test_BadSourceBelow(self):
  445. def fn():
  446. scheme = {
  447. 'h': {
  448. 'ua': hoover.Cartman.Iterable,
  449. },
  450. 'p': hoover.Cartman.Iterable,
  451. 'd': hoover.Cartman.Iterable
  452. }
  453. source = {
  454. 'h': 'NOT A CORRESPONDING OBJECT',
  455. 'p': ['a', 'b'],
  456. 'd': [False, True]
  457. }
  458. next(iter(hoover.Cartman(source, scheme)))
  459. self.assertRaises(ValueError, fn)
  460. def test_BadMark(self):
  461. def fn():
  462. class a_mark(hoover.Cartman._BaseMark):
  463. pass
  464. scheme = {
  465. 'a': hoover.Cartman.Iterable,
  466. 'b': hoover.Cartman.Iterable,
  467. 'c': a_mark
  468. }
  469. source = dict.fromkeys(scheme, [])
  470. next(iter(hoover.Cartman(source, scheme)))
  471. self.assertRaises(ValueError, fn)
  472. class RuleOpTest(unittest.TestCase):
  473. # basic cases
  474. def testAllEmpty(self):
  475. oracle = True
  476. result = hoover.RuleOp.Match((hoover.RuleOp.ALL, []), bool)
  477. self.assertEqual(oracle, result)
  478. def testAllTrue(self):
  479. oracle = True
  480. result = hoover.RuleOp.Match((hoover.RuleOp.ALL, [1, 1, 1]), bool)
  481. self.assertEqual(oracle, result)
  482. def testAllMixed(self):
  483. oracle = False
  484. result = hoover.RuleOp.Match((hoover.RuleOp.ALL, [1, 0, 1]), bool)
  485. self.assertEqual(oracle, result)
  486. def testAllFalse(self):
  487. oracle = False
  488. result = hoover.RuleOp.Match((hoover.RuleOp.ALL, [0, 0, 0]), bool)
  489. self.assertEqual(oracle, result)
  490. def testAnyEmpty(self):
  491. oracle = False
  492. result = hoover.RuleOp.Match((hoover.RuleOp.ANY, []), bool)
  493. self.assertEqual(oracle, result)
  494. def testAnyTrue(self):
  495. oracle = True
  496. result = hoover.RuleOp.Match((hoover.RuleOp.ANY, [1, 1, 1]), bool)
  497. self.assertEqual(oracle, result)
  498. def testAnyMixed(self):
  499. oracle = True
  500. result = hoover.RuleOp.Match((hoover.RuleOp.ANY, [1, 0, 1]), bool)
  501. self.assertEqual(oracle, result)
  502. def testAnyFalse(self):
  503. oracle = False
  504. result = hoover.RuleOp.Match((hoover.RuleOp.ANY, [0, 0, 0]), bool)
  505. self.assertEqual(oracle, result)
  506. # nesting
  507. def testAnyAllTrue(self):
  508. patt = (hoover.RuleOp.ANY, [(hoover.RuleOp.ALL, [1, 1]), 0, 0])
  509. oracle = True
  510. result = hoover.RuleOp.Match(patt, bool)
  511. self.assertEqual(oracle, result)
  512. def testAllAnyFalse(self):
  513. patt = (hoover.RuleOp.ALL, [1, (hoover.RuleOp.ANY, [0, 0]), 1, 1])
  514. oracle = False
  515. result = hoover.RuleOp.Match(patt, bool)
  516. self.assertEqual(oracle, result)
  517. # error handling
  518. def testBadOpClass(self):
  519. class bad_op:
  520. def _match(self):
  521. return True
  522. fn = lambda: hoover.RuleOp.Match(((bad_op, [])), bool)
  523. self.assertRaises(ValueError, fn)
  524. def testBadOpNonClass(self):
  525. fn = lambda: hoover.RuleOp.Match((("bad_op", [])), bool)
  526. self.assertRaises(ValueError, fn)
  527. def testBadPatternScalar(self):
  528. fn = lambda: hoover.RuleOp.Match(43, bool)
  529. self.assertRaises(ValueError, fn)
  530. def testBadPatternShort(self):
  531. fn = lambda: hoover.RuleOp.Match((43,), bool)
  532. self.assertRaises(ValueError, fn)
  533. def testBadPatternLong(self):
  534. fn = lambda: hoover.RuleOp.Match((43, 41, 42), bool)
  535. self.assertRaises(ValueError, fn)
  536. def testBadItems(self):
  537. fn = lambda: hoover.RuleOp.Match(((hoover.RuleOp.ALL, 1)), bool)
  538. self.assertRaises(ValueError, fn)
  539. # own operator
  540. def testOwnOp(self):
  541. class MYOP(hoover._BaseRuleOp):
  542. def _match(self):
  543. return True
  544. oracle = True
  545. result = hoover.RuleOp.Match((MYOP, [0, 1, 2]), bool)
  546. self.assertEqual(oracle, result)
  547. class JsDiff(unittest.TestCase):
  548. def setUp(self):
  549. self.a = {
  550. 'joe': 31,
  551. 'johnny': 55,
  552. 'twins': {
  553. 'al': 1,
  554. 'bo': 1,
  555. 'ww': 1
  556. },
  557. 'annie': 1,
  558. 'todo': [
  559. 'buy milk',
  560. 'visit aunt Emma',
  561. {'buy presents': [
  562. 'for daddy',
  563. 'for mommy',
  564. 'for sister',
  565. 'for brother'
  566. ]},
  567. 'stop smoking',
  568. 'make less promises'
  569. ],
  570. 'stones': [
  571. 'red stone',
  572. 'stone',
  573. 'get stoned'
  574. ]
  575. }
  576. self.b = {
  577. 'joe': 31,
  578. 'johnny': 55,
  579. 'twins': {
  580. 'al': 1,
  581. 'bo': 1,
  582. 'ww': 1
  583. },
  584. 'annie': 3,
  585. 'todo': [
  586. 'buy milk',
  587. {'buy presents': [
  588. 'for sister',
  589. 'for brother'
  590. ]},
  591. 'stop smoking',
  592. 'take over the world',
  593. 'make less promises'
  594. ],
  595. 'tamara': 110,
  596. 'stones': [
  597. 'red stone',
  598. 'moonstone',
  599. 'stone',
  600. 'get stoned'
  601. ]
  602. }
  603. def testDense(self):
  604. oracle = (
  605. 'aaa ~/A\n'
  606. ' {\n'
  607. 'a "annie": 1,\n'
  608. ' "stones": [\n'
  609. ' "todo": [\n'
  610. 'a "visit aunt Emma",\n'
  611. ' "buy presents": [\n'
  612. 'a "for daddy",\n'
  613. 'a "for mommy",\n'
  614. 'bbb ~/B\n'
  615. ' {\n'
  616. 'b "annie": 3,\n'
  617. ' "stones": [\n'
  618. 'b "moonstone",\n'
  619. 'b "tamara": 110,\n'
  620. ' "todo": [\n'
  621. ' "buy presents": [\n'
  622. 'b "take over the world",'
  623. )
  624. result = hoover.jsDiff(self.a, self.b)
  625. self.assertEqual(oracle, result)
  626. class DataMatch(unittest.TestCase):
  627. class sdict(dict):
  628. pass
  629. class slist(list):
  630. pass
  631. def setUp(self):
  632. super(DataMatch, self).setUp()
  633. # dict
  634. def test_Dict_Ok(self):
  635. p = { 1: 2 }
  636. r = { 1: 2, 3: 4 }
  637. self.assertTrue(hoover.dataMatch(p, r))
  638. def test_Dict_Nok(self):
  639. p = { 1: 2 }
  640. r = { 1: 3, 3: 4 }
  641. self.assertFalse(hoover.dataMatch(p, r))
  642. def test_DictDict_Ok(self):
  643. p = { 'a': { 'A': 'B' } }
  644. r = { 1: 2, 'a': { 'A': 'B' } }
  645. self.assertTrue(hoover.dataMatch(p, r))
  646. def test_DictDict_Nok(self):
  647. p = { 'a': { 'A': 'B' } }
  648. r = { 1: 2, 'a': { 'C': 'D' } }
  649. self.assertFalse(hoover.dataMatch(p, r))
  650. def test_DictList_Ok(self):
  651. p = { 3: [ 11, 12 ] }
  652. r = { 1: 2, 3: [ 10, 11, 12, 13 ] }
  653. self.assertTrue(hoover.dataMatch(p, r))
  654. def test_DictList_Nok(self):
  655. p = { 3: [ 11, 12 ] }
  656. r = { 1: 2, 3: [ 10, 11, 13 ] }
  657. self.assertFalse(hoover.dataMatch(p, r))
  658. # list
  659. def test_List_Ok(self):
  660. p = [ 101, 102 ]
  661. r = [ 101, 103, 102 ]
  662. self.assertTrue(hoover.dataMatch(p, r))
  663. def test_List_Nok(self):
  664. p = [ 101, 102 ]
  665. r = [ 101, 103 ]
  666. self.assertFalse(hoover.dataMatch(p, r))
  667. def test_ListList_Ok(self):
  668. p = [ 101, ['a', 'b'], 102 ]
  669. r = [ 101, [1, 'a', 2, 'b'], 103, 102 ]
  670. self.assertTrue(hoover.dataMatch(p, r))
  671. def test_ListDict_Ok(self):
  672. p = [ 101, {'a': 'A'}, 102 ]
  673. r = [ 101, {'a': 'A', 'b': 'B'}, 103, 102 ]
  674. self.assertTrue(hoover.dataMatch(p, r))
  675. def test_ListDict_Nok(self):
  676. p = [ 101, {'a': 'A'}, 102 ]
  677. r = [ 101, {'a': 'X', 'b': 'B'}, 103, 102 ]
  678. self.assertFalse(hoover.dataMatch(p, r))
  679. # dict/list subclass
  680. def test_DictPSub_Ok(self):
  681. p = self.sdict({ 1: 2 })
  682. r = { 1: 2, 3: 4 }
  683. self.assertTrue(hoover.dataMatch(p, r))
  684. def test_DictPSub_Nok(self):
  685. p = self.sdict({ 1: 2 })
  686. r = { 1: 3, 3: 4 }
  687. self.assertFalse(hoover.dataMatch(p, r))
  688. def test_DictRSub_Ok(self):
  689. p = { 1: 2 }
  690. r = self.sdict({ 1: 2, 3: 4 })
  691. self.assertTrue(hoover.dataMatch(p, r))
  692. def test_DictRSub_Nok(self):
  693. p = { 1: 2 }
  694. r = self.sdict({ 1: 3, 3: 4 })
  695. self.assertFalse(hoover.dataMatch(p, r))
  696. def test_DictPRSub_Ok(self):
  697. p = self.sdict({ 1: 2 })
  698. r = self.sdict({ 1: 2, 3: 4 })
  699. self.assertTrue(hoover.dataMatch(p, r))
  700. def test_DictPRSub_Nok(self):
  701. p = self.sdict({ 1: 2 })
  702. r = self.sdict({ 1: 3, 3: 4 })
  703. self.assertFalse(hoover.dataMatch(p, r))
  704. def test_ListPSub_Ok(self):
  705. p = self.slist([ 101, 102 ])
  706. r = [ 101, 103, 102 ]
  707. self.assertTrue(hoover.dataMatch(p, r))
  708. def test_ListPSub_Nok(self):
  709. p = self.slist([ 101, 102 ])
  710. r = [ 101, 103 ]
  711. self.assertFalse(hoover.dataMatch(p, r))
  712. def test_ListRSub_Ok(self):
  713. p = [ 101, 102 ]
  714. r = self.slist([ 101, 103, 102 ])
  715. self.assertTrue(hoover.dataMatch(p, r))
  716. def test_ListRSub_Nok(self):
  717. p = [ 101, 102 ]
  718. r = self.slist([ 101, 103 ])
  719. self.assertFalse(hoover.dataMatch(p, r))
  720. def test_ListPRSub_Ok(self):
  721. p = self.slist([ 101, 102 ])
  722. r = self.slist([ 101, 103, 102 ])
  723. self.assertTrue(hoover.dataMatch(p, r))
  724. def test_ListPRSub_Nok(self):
  725. p = self.slist([ 101, 102 ])
  726. r = self.slist([ 101, 103 ])
  727. self.assertFalse(hoover.dataMatch(p, r))
  728. if __name__ == "__main__":
  729. unittest.main()