test_jsinterp.py 5.7 KB

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