PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/jasy/test/blockreduce.py

http://github.com/zynga/jasy
Python | 528 lines | 514 code | 12 blank | 2 comment | 0 complexity | 09b7e969fc5046f159228cbe624ab6d7 MD5 | raw file
  1. #!/usr/bin/env python3
  2. import sys, os, unittest, logging, pkg_resources
  3. # Extend PYTHONPATH with local 'lib' folder
  4. jasyroot = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir, os.pardir))
  5. sys.path.insert(0, jasyroot)
  6. import jasy.js.parse.Parser as Parser
  7. import jasy.js.parse.ScopeScanner as ScopeScanner
  8. import jasy.js.output.Compressor as Compressor
  9. import jasy.js.optimize.BlockReducer as BlockReducer
  10. class Tests(unittest.TestCase):
  11. def process(self, code):
  12. node = Parser.parse(code)
  13. BlockReducer.optimize(node)
  14. return Compressor.Compressor().compress(node)
  15. def test_combine_mixed(self):
  16. self.assertEqual(self.process('var str = 4 + 3 + "x"'), 'var str="7x";')
  17. def test_combine_number(self):
  18. self.assertEqual(self.process('var adds = 4 * (5+6);'), 'var adds=44;')
  19. def test_combine_number_omit(self):
  20. self.assertEqual(self.process('var third = 1/3;'), 'var third=1/3;')
  21. def test_combine_string(self):
  22. self.assertEqual(self.process('var result = "first second third " + "fourth fivs sixs";'), 'var result="first second third fourth fivs sixs";')
  23. def test_combine_mixed_empty(self):
  24. self.assertEqual(self.process('4 + 3 + "x"'), '')
  25. def test_elseinline_return(self):
  26. self.assertEqual(self.process(
  27. '''
  28. function x()
  29. {
  30. if (something)
  31. {
  32. x++;
  33. while(warm) {}
  34. return x;
  35. }
  36. else
  37. {
  38. y++;
  39. }
  40. }
  41. '''),
  42. 'function x(){if(something){x++;while(warm);return x}y++}'
  43. )
  44. def test_elseinline_throw(self):
  45. self.assertEqual(self.process(
  46. '''
  47. function x()
  48. {
  49. if (something)
  50. {
  51. x++;
  52. while(warm) {}
  53. throw new Error("Wrong data!");
  54. }
  55. else
  56. {
  57. y++;
  58. }
  59. }
  60. '''),
  61. 'function x(){if(something){x++;while(warm);throw new Error("Wrong data!")}y++}'
  62. )
  63. def test_elseinline_elseif(self):
  64. self.assertEqual(self.process(
  65. '''
  66. function x()
  67. {
  68. if(something)
  69. {
  70. while(a);
  71. return 0;
  72. }
  73. else if(xxx)
  74. {
  75. while(b);
  76. return 1;
  77. }
  78. else
  79. {
  80. while(c);
  81. return 2;
  82. }
  83. }
  84. '''),
  85. 'function x(){if(something){while(a);return 0}if(xxx){while(b);return 1}while(c);return 2}'
  86. )
  87. def test_elseinline_elseif_nolast(self):
  88. self.assertEqual(self.process(
  89. '''
  90. function x()
  91. {
  92. if(something)
  93. {
  94. while(a);
  95. return 0;
  96. }
  97. else if(xxx)
  98. {
  99. while(b);
  100. return 1;
  101. }
  102. else
  103. {
  104. i++;
  105. }
  106. }
  107. '''),
  108. 'function x(){if(something){while(a);return 0}if(xxx){while(b);return 1}i++}'
  109. )
  110. def test_elseinline_cascaded(self):
  111. self.assertEqual(self.process(
  112. '''
  113. function x()
  114. {
  115. if(something)
  116. {
  117. while(x);
  118. return 0;
  119. }
  120. else if(xxx)
  121. {
  122. if(test2())
  123. {
  124. while(x);
  125. return 1;
  126. }
  127. else if(test3())
  128. {
  129. while(x);
  130. return 2;
  131. }
  132. else
  133. {
  134. while(x);
  135. return 3;
  136. }
  137. }
  138. else
  139. {
  140. while(x);
  141. return 4;
  142. }
  143. }
  144. '''),
  145. 'function x(){if(something){while(x);return 0}if(xxx){if(test2()){while(x);return 1}if(test3()){while(x);return 2}while(x);return 3}while(x);return 4}'
  146. )
  147. def test_if_deep_if(self):
  148. self.assertEqual(self.process(
  149. '''
  150. if(something)
  151. {
  152. for(g in h)
  153. {
  154. x++;
  155. if(otherthing){
  156. y++;
  157. while(bar);
  158. }
  159. }
  160. }
  161. '''),
  162. 'if(something)for(g in h){x++;if(otherthing){y++;while(bar);}}'
  163. )
  164. def test_loop_brackets(self):
  165. self.assertEqual(self.process(
  166. '''
  167. while(true)
  168. {
  169. retVal = !!callback(elems[i],i);
  170. if (inv!==retVal) {
  171. ret.push(elems[i])
  172. }
  173. }
  174. '''),
  175. 'while(true)retVal=!!callback(elems[i],i),inv!==retVal&&ret.push(elems[i]);'
  176. )
  177. def test_switch_return(self):
  178. self.assertEqual(self.process(
  179. '''
  180. function wrapper(code)
  181. {
  182. switch(code)
  183. {
  184. case null:
  185. case 0:
  186. return true;
  187. case -1:
  188. return false;
  189. }
  190. }
  191. '''),
  192. 'function wrapper(code){switch(code){case null:case 0:return true;case -1:return false}}'
  193. )
  194. def test_if_else_cascaded(self):
  195. self.assertEqual(self.process(
  196. '''
  197. if(something)
  198. {
  199. if (condition)
  200. {
  201. somethingCase1a();
  202. somethingCase1b();
  203. }
  204. else
  205. {
  206. somethingCase2a();
  207. somethingCase2b();
  208. }
  209. }
  210. else
  211. {
  212. otherStuffA();
  213. otherStuffB();
  214. }
  215. '''),
  216. 'something?condition?(somethingCase1a(),somethingCase1b()):(somethingCase2a(),somethingCase2b()):(otherStuffA(),otherStuffB());'
  217. )
  218. def test_if_else_expression(self):
  219. self.assertEqual(self.process(
  220. '''
  221. if(foo)
  222. {
  223. x++;
  224. }
  225. else
  226. {
  227. x--;
  228. }
  229. '''),
  230. 'foo?x++:x--;'
  231. )
  232. def test_if_else_both_empty(self):
  233. self.assertEqual(self.process(
  234. '''
  235. function wrapper()
  236. {
  237. if(something)
  238. {}
  239. else
  240. {}
  241. }
  242. '''),
  243. 'function wrapper(){something}'
  244. )
  245. def test_if_else_empty(self):
  246. self.assertEqual(self.process(
  247. '''
  248. function wrapper()
  249. {
  250. if(something)
  251. {
  252. while(x);
  253. }
  254. else
  255. {}
  256. }
  257. '''),
  258. 'function wrapper(){if(something)while(x);}'
  259. )
  260. def test_if_else_while_if(self):
  261. self.assertEqual(self.process(
  262. '''
  263. if(first)
  264. {
  265. while(second)
  266. {
  267. if(x)
  268. {
  269. x++;
  270. }
  271. }
  272. }
  273. else
  274. {
  275. y++;
  276. }
  277. '''),
  278. 'if(first)while(second)x&&x++;else y++;'
  279. )
  280. def test_if_empty_else(self):
  281. self.assertEqual(self.process(
  282. '''
  283. function wrapper()
  284. {
  285. if(something)
  286. {
  287. }
  288. else
  289. {
  290. while(x);
  291. }
  292. }
  293. '''),
  294. 'function wrapper(){if(!something)while(x);}'
  295. )
  296. def test_if_empty_else_two(self):
  297. self.assertEqual(self.process(
  298. '''
  299. function wrapper()
  300. {
  301. if(something && otherthing)
  302. {
  303. }
  304. else
  305. {
  306. while(x);
  307. }
  308. }
  309. '''),
  310. 'function wrapper(){if(!(something&&otherthing))while(x);}'
  311. )
  312. def test_ifoptimize_assign_late(self):
  313. self.assertEqual(self.process(
  314. '''
  315. if(something) {
  316. x++;
  317. x=4;
  318. }
  319. '''),
  320. 'something&&(x++,x=4);'
  321. )
  322. def test_ifoptimize_assign(self):
  323. self.assertEqual(self.process(
  324. '''
  325. if (something) {
  326. x = 4;
  327. }
  328. '''),
  329. 'something&&(x=4);'
  330. )
  331. def test_ifoptimize_crazy(self):
  332. self.assertEqual(self.process(
  333. 'if (X && !this.isRich()) { {}; }'),
  334. 'X&&!this.isRich();'
  335. )
  336. def test_ifoptimize_empty(self):
  337. self.assertEqual(self.process(
  338. 'if(something){}'),
  339. 'something;'
  340. )
  341. def test_mergeassign_assign(self):
  342. self.assertEqual(self.process(
  343. '''
  344. if(foo)
  345. {
  346. x = 5;
  347. }
  348. else
  349. {
  350. x = 7;
  351. }
  352. '''),
  353. 'x=foo?5:7;'
  354. )
  355. def test_mergeassign_assign_plus(self):
  356. self.assertEqual(self.process(
  357. '''
  358. if(something) {
  359. x += 3;
  360. } else {
  361. x += 4;
  362. }
  363. '''),
  364. 'x+=something?3:4;'
  365. )
  366. def test_mergeassign_object(self):
  367. self.assertEqual(self.process(
  368. '''
  369. if(something) {
  370. obj.foo.bar = "hello";
  371. } else {
  372. obj.foo.bar = "world";
  373. }
  374. '''),
  375. 'obj.foo.bar=something?"hello":"world";'
  376. )
  377. def test_mergereturn(self):
  378. self.assertEqual(self.process(
  379. '''
  380. function ret()
  381. {
  382. if(something) {
  383. return "hello";
  384. } else {
  385. return "world";
  386. }
  387. }
  388. '''),
  389. 'function ret(){return something?"hello":"world"}'
  390. )
  391. def test_parens_arithm(self):
  392. self.assertEqual(self.process(
  393. 'x=(4*5)+4;'),
  394. 'x=24;'
  395. )
  396. def test_parens_assign(self):
  397. self.assertEqual(self.process(
  398. 'doc = (context ? context.ownerDocument || context : document);'),
  399. 'doc=context?context.ownerDocument||context:document;'
  400. )
  401. def test_parens_condition(self):
  402. self.assertEqual(self.process(
  403. '''
  404. while ( (fn = readyList[ i++ ]) ) {
  405. fn.call( document, jQuery );
  406. }
  407. '''),
  408. 'while(fn=readyList[i++])fn.call(document,jQuery);'
  409. )
  410. def test_parens_directexec(self):
  411. self.assertEqual(self.process(
  412. '(function(){ x++; })();'),
  413. '(function(){x++})();'
  414. )
  415. def test_parens_new(self):
  416. self.assertEqual(self.process(
  417. 'var x = (new some.special.Item).setText("Hello World");'),
  418. 'var x=(new some.special.Item).setText("Hello World");'
  419. )
  420. def test_parens_new_args(self):
  421. self.assertEqual(self.process(
  422. 'var x = new some.special.Item("param").setText("Hello World");'),
  423. 'var x=new some.special.Item("param").setText("Hello World");'
  424. )
  425. def test_parens_return(self):
  426. self.assertEqual(self.process(
  427. '''
  428. function x() {
  429. return (somemethod() && othermethod() != null);
  430. }
  431. '''),
  432. 'function x(){return somemethod()&&othermethod()!=null}'
  433. )
  434. def test_parens_numberoper(self):
  435. self.assertEqual(self.process('''(23).pad(2);'''), '(23).pad(2);')
  436. def test_single_command_if_block(self):
  437. self.assertEqual(self.process(
  438. '''
  439. if (!abc) {
  440. abc = {
  441. setup: function() {
  442. if (cde) {
  443. x();
  444. } else {
  445. return false;
  446. }
  447. }
  448. };
  449. }
  450. '''),
  451. 'abc||(abc={setup:function(){if(cde)x();else return false}});'
  452. )
  453. def test_strict(self):
  454. self.assertEqual(self.process(
  455. '''
  456. function foo() {
  457. "use strict";
  458. doSomething();
  459. }
  460. foo();
  461. '''),
  462. 'function foo(){"use strict";doSomething()}foo();'
  463. )
  464. if __name__ == '__main__':
  465. logging.getLogger().setLevel(logging.ERROR)
  466. suite = unittest.TestLoader().loadTestsFromTestCase(Tests)
  467. unittest.TextTestRunner(verbosity=2).run(suite)