test_jsinterp.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/usr/bin/env python
  2. from __future__ import unicode_literals
  3. # Allow direct execution
  4. import os
  5. import sys
  6. import unittest
  7. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  8. from youtube_dl.jsinterp import JSInterpreter
  9. class TestJSInterpreter(unittest.TestCase):
  10. def test_basic(self):
  11. jsi = JSInterpreter('function x(){;}')
  12. self.assertEqual(jsi.call_function('x'), None)
  13. jsi = JSInterpreter('function x3(){return 42;}')
  14. self.assertEqual(jsi.call_function('x3'), 42)
  15. jsi = JSInterpreter('function x3(){42}')
  16. self.assertEqual(jsi.call_function('x3'), None)
  17. jsi = JSInterpreter('var x5 = function(){return 42;}')
  18. self.assertEqual(jsi.call_function('x5'), 42)
  19. def test_calc(self):
  20. jsi = JSInterpreter('function x4(a){return 2*a+1;}')
  21. self.assertEqual(jsi.call_function('x4', 3), 7)
  22. def test_empty_return(self):
  23. jsi = JSInterpreter('function f(){return; y()}')
  24. self.assertEqual(jsi.call_function('f'), None)
  25. def test_morespace(self):
  26. jsi = JSInterpreter('function x (a) { return 2 * a + 1 ; }')
  27. self.assertEqual(jsi.call_function('x', 3), 7)
  28. jsi = JSInterpreter('function f () { x = 2 ; return x; }')
  29. self.assertEqual(jsi.call_function('f'), 2)
  30. def test_strange_chars(self):
  31. jsi = JSInterpreter('function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; }')
  32. self.assertEqual(jsi.call_function('$_xY1', 20), 21)
  33. def test_operators(self):
  34. jsi = JSInterpreter('function f(){return 1 << 5;}')
  35. self.assertEqual(jsi.call_function('f'), 32)
  36. jsi = JSInterpreter('function f(){return 19 & 21;}')
  37. self.assertEqual(jsi.call_function('f'), 17)
  38. jsi = JSInterpreter('function f(){return 11 >> 2;}')
  39. self.assertEqual(jsi.call_function('f'), 2)
  40. jsi = JSInterpreter('function f(){return []? 2+3: 4;}')
  41. self.assertEqual(jsi.call_function('f'), 5)
  42. def test_array_access(self):
  43. jsi = JSInterpreter('function f(){var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2.0] = 7; return x;}')
  44. self.assertEqual(jsi.call_function('f'), [5, 2, 7])
  45. def test_parens(self):
  46. jsi = JSInterpreter('function f(){return (1) + (2) * ((( (( (((((3)))))) )) ));}')
  47. self.assertEqual(jsi.call_function('f'), 7)
  48. jsi = JSInterpreter('function f(){return (1 + 2) * 3;}')
  49. self.assertEqual(jsi.call_function('f'), 9)
  50. def test_quotes(self):
  51. jsi = JSInterpreter(r'function f(){return "a\"\\("}')
  52. self.assertEqual(jsi.call_function('f'), r'a"\(')
  53. def test_assignments(self):
  54. jsi = JSInterpreter('function f(){var x = 20; x = 30 + 1; return x;}')
  55. self.assertEqual(jsi.call_function('f'), 31)
  56. jsi = JSInterpreter('function f(){var x = 20; x += 30 + 1; return x;}')
  57. self.assertEqual(jsi.call_function('f'), 51)
  58. jsi = JSInterpreter('function f(){var x = 20; x -= 30 + 1; return x;}')
  59. self.assertEqual(jsi.call_function('f'), -11)
  60. def test_comments(self):
  61. 'Skipping: Not yet fully implemented'
  62. return
  63. jsi = JSInterpreter('''
  64. function x() {
  65. var x = /* 1 + */ 2;
  66. var y = /* 30
  67. * 40 */ 50;
  68. return x + y;
  69. }
  70. ''')
  71. self.assertEqual(jsi.call_function('x'), 52)
  72. jsi = JSInterpreter('''
  73. function f() {
  74. var x = "/*";
  75. var y = 1 /* comment */ + 2;
  76. return y;
  77. }
  78. ''')
  79. self.assertEqual(jsi.call_function('f'), 3)
  80. def test_precedence(self):
  81. jsi = JSInterpreter('''
  82. function x() {
  83. var a = [10, 20, 30, 40, 50];
  84. var b = 6;
  85. a[0]=a[b%a.length];
  86. return a;
  87. }''')
  88. self.assertEqual(jsi.call_function('x'), [20, 20, 30, 40, 50])
  89. def test_builtins(self):
  90. jsi = JSInterpreter('''
  91. function x() { return new Date('Wednesday 31 December 1969 18:01:26 MDT') - 0; }
  92. ''')
  93. self.assertEqual(jsi.call_function('x'), 86000)
  94. jsi = JSInterpreter('''
  95. function x(dt) { return new Date(dt) - 0; }
  96. ''')
  97. self.assertEqual(jsi.call_function('x', 'Wednesday 31 December 1969 18:01:26 MDT'), 86000)
  98. def test_call(self):
  99. jsi = JSInterpreter('''
  100. function x() { return 2; }
  101. function y(a) { return x() + (a?a:0); }
  102. function z() { return y(3); }
  103. ''')
  104. self.assertEqual(jsi.call_function('z'), 5)
  105. self.assertEqual(jsi.call_function('y'), 2)
  106. def test_for_loop(self):
  107. # function x() { a=0; for (i=0; i-10; i++) {a++} a }
  108. jsi = JSInterpreter('''
  109. function x() { a=0; for (i=0; i-10; i++) {a++} return a }
  110. ''')
  111. self.assertEqual(jsi.call_function('x'), 10)
  112. def test_switch(self):
  113. jsi = JSInterpreter('''
  114. function x(f) { switch(f){
  115. case 1:f+=1;
  116. case 2:f+=2;
  117. case 3:f+=3;break;
  118. case 4:f+=4;
  119. default:f=0;
  120. } return f }
  121. ''')
  122. self.assertEqual(jsi.call_function('x', 1), 7)
  123. self.assertEqual(jsi.call_function('x', 3), 6)
  124. self.assertEqual(jsi.call_function('x', 5), 0)
  125. def test_switch_default(self):
  126. jsi = JSInterpreter('''
  127. function x(f) { switch(f){
  128. case 2: f+=2;
  129. default: f-=1;
  130. case 5:
  131. case 6: f+=6;
  132. case 0: break;
  133. case 1: f+=1;
  134. } return f }
  135. ''')
  136. self.assertEqual(jsi.call_function('x', 1), 2)
  137. self.assertEqual(jsi.call_function('x', 5), 11)
  138. self.assertEqual(jsi.call_function('x', 9), 14)
  139. def test_try(self):
  140. jsi = JSInterpreter('''
  141. function x() { try{return 10} catch(e){return 5} }
  142. ''')
  143. self.assertEqual(jsi.call_function('x'), 10)
  144. def test_for_loop_continue(self):
  145. jsi = JSInterpreter('''
  146. function x() { a=0; for (i=0; i-10; i++) { continue; a++ } return a }
  147. ''')
  148. self.assertEqual(jsi.call_function('x'), 0)
  149. def test_for_loop_break(self):
  150. jsi = JSInterpreter('''
  151. function x() { a=0; for (i=0; i-10; i++) { break; a++ } return a }
  152. ''')
  153. self.assertEqual(jsi.call_function('x'), 0)
  154. def test_literal_list(self):
  155. jsi = JSInterpreter('''
  156. function x() { return [1, 2, "asdf", [5, 6, 7]][3] }
  157. ''')
  158. self.assertEqual(jsi.call_function('x'), [5, 6, 7])
  159. def test_comma(self):
  160. jsi = JSInterpreter('''
  161. function x() { a=5; a -= 1, a+=3; return a }
  162. ''')
  163. self.assertEqual(jsi.call_function('x'), 7)
  164. jsi = JSInterpreter('''
  165. function x() { a=5; return (a -= 1, a+=3, a); }
  166. ''')
  167. self.assertEqual(jsi.call_function('x'), 7)
  168. def test_void(self):
  169. jsi = JSInterpreter('''
  170. function x() { return void 42; }
  171. ''')
  172. self.assertEqual(jsi.call_function('x'), None)
  173. def test_return_function(self):
  174. jsi = JSInterpreter('''
  175. function x() { return [1, function(){return 1}][1] }
  176. ''')
  177. self.assertEqual(jsi.call_function('x')([]), 1)
  178. if __name__ == '__main__':
  179. unittest.main()