@ -11,194 +11,146 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import math
import math
import re
import re
from youtube_dl . compat import compat_str
from youtube_dl . jsinterp import JS_Undefined , JSInterpreter
from youtube_dl . jsinterp import JS_Undefined , JSInterpreter
NaN = object ( )
class TestJSInterpreter ( unittest . TestCase ) :
def test_basic ( self ) :
jsi = JSInterpreter ( ' function x() { ;} ' )
self . assertEqual ( jsi . call_function ( ' x ' ) , None )
self . assertEqual ( repr ( jsi . extract_function ( ' x ' ) ) , ' F<x> ' )
jsi = JSInterpreter ( ' function x3() { return 42;} ' )
self . assertEqual ( jsi . call_function ( ' x3 ' ) , 42 )
jsi = JSInterpreter ( ' function x3() {42} ' )
class TestJSInterpreter ( unittest . TestCase ) :
self . assertEqual ( jsi . call_function ( ' x3 ' ) , None )
def _test ( self , jsi_or_code , expected , func = ' f ' , args = ( ) ) :
if isinstance ( jsi_or_code , compat_str ) :
jsi_or_code = JSInterpreter ( jsi_or_code )
got = jsi_or_code . call_function ( func , * args )
if expected is NaN :
self . assertTrue ( math . isnan ( got ) , ' {0} is not NaN ' . format ( got ) )
else :
self . assertEqual ( got , expected )
jsi = JSInterpreter ( ' var x5 = function() { return 42;} ' )
def test_basic ( self ) :
self . assertEqual ( jsi . call_function ( ' x5 ' ) , 42 )
jsi = JSInterpreter ( ' function f() { ;} ' )
self . assertEqual ( repr ( jsi . extract_function ( ' f ' ) ) , ' F<f> ' )
self . _test ( jsi , None )
def test_calc ( self ) :
self . _test ( ' function f() { return 42;} ' , 42 )
jsi = JSInterpreter ( ' function x4(a) { return 2*a+1;} ' )
self . _test ( ' function f() {42} ' , None )
self . assertEqual ( jsi . call_function ( ' x4 ' , 3 ) , 7 )
self . _test( ' var f = function() { return 42;} ' , 42 )
def test_add ( self ) :
def test_add ( self ) :
jsi = JSInterpreter ( ' function f() { return 42 + 7;} ' )
self . _test ( ' function f() { return 42 + 7;} ' , 49 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 49 )
self . _test ( ' function f() { return 42 + undefined;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 + undefined;} ' )
self . _test ( ' function f() { return 42 + null;} ' , 42 )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
jsi = JSInterpreter ( ' function f() { return 42 + null;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 42 )
def test_sub ( self ) :
def test_sub ( self ) :
jsi = JSInterpreter ( ' function f() { return 42 - 7;} ' )
self . _test ( ' function f() { return 42 - 7;} ' , 35 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 35 )
self . _test ( ' function f() { return 42 - undefined;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 - undefined;} ' )
self . _test ( ' function f() { return 42 - null;} ' , 42 )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
jsi = JSInterpreter ( ' function f() { return 42 - null;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 42 )
def test_mul ( self ) :
def test_mul ( self ) :
jsi = JSInterpreter ( ' function f() { return 42 * 7;} ' )
self . _test ( ' function f() { return 42 * 7;} ' , 294 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 294 )
self . _test ( ' function f() { return 42 * undefined;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 * undefined;} ' )
self . _test ( ' function f() { return 42 * null;} ' , 0 )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
jsi = JSInterpreter ( ' function f() { return 42 * null;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 0 )
def test_div ( self ) :
def test_div ( self ) :
jsi = JSInterpreter ( ' function f(a, b) { return a / b;} ' )
jsi = JSInterpreter ( ' function f(a, b) { return a / b;} ' )
self . assertTrue( math . isnan ( jsi . call_function ( ' f ' , 0 , 0 ) ) )
self . _test( jsi , NaN , args = ( 0 , 0 ) )
self . assertTrue( math . isnan ( jsi . call_function ( ' f ' , JS_Undefined , 1 ) ) )
self . _test( jsi , NaN , args = ( JS_Undefined , 1 ) )
self . assertTrue( math . isinf ( jsi . call_function ( ' f ' , 2 , 0 ) ) )
self . _test( jsi , float ( ' inf ' ) , args = ( 2 , 0 ) )
self . assertEqual( jsi . call_function ( ' f ' , 0 , 3 ) , 0 )
self . _test( jsi , 0 , args = ( 0 , 3 ) )
def test_mod ( self ) :
def test_mod ( self ) :
jsi = JSInterpreter ( ' function f() { return 42 % 7;} ' )
self . _test ( ' function f() { return 42 % 7;} ' , 0 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 0 )
self . _test ( ' function f() { return 42 % 0;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 % 0;} ' )
self . _test ( ' function f() { return 42 % u ndefined;} ' , NaN )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
jsi = JSInterpreter ( ' function f() { return 42 % u ndefined;} ' )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
def test_exp ( self ) :
def test_exp ( self ) :
jsi = JSInterpreter ( ' function f() { return 42 ** 2;} ' )
self . _test ( ' function f() { return 42 ** 2;} ' , 1764 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 1764 )
self . _test ( ' function f() { return 42 ** undefined;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 ** undefined;} ' )
self . _test ( ' function f() { return 42 ** null;} ' , 1 )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
self . _test ( ' function f() { return undefined ** 42;} ' , NaN )
jsi = JSInterpreter ( ' function f() { return 42 ** null;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 1 )
def test_calc ( self ) :
jsi = JSInterpreter ( ' function f() { return undefined ** 42;} ' )
self . _test ( ' function f(a) { return 2*a+1;} ' , 7 , args = [ 3 ] )
self . assertTrue ( math . isnan ( jsi . call_function ( ' f ' ) ) )
def test_empty_return ( self ) :
def test_empty_return ( self ) :
jsi = JSInterpreter ( ' function f() { return; y()} ' )
self . _test ( ' function f() { return; y()} ' , None )
self . assertEqual ( jsi . call_function ( ' f ' ) , None )
def test_morespace ( self ) :
def test_morespace ( self ) :
jsi = JSInterpreter ( ' function x (a) { return 2 * a + 1 ; } ' )
self . _test ( ' function f (a) { return 2 * a + 1 ; } ' , 7 , args = [ 3 ] )
self . assertEqual ( jsi . call_function ( ' x ' , 3 ) , 7 )
self . _test ( ' function f () { x = 2 ; return x; } ' , 2 )
jsi = JSInterpreter ( ' function f () { x = 2 ; return x; } ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 2 )
def test_strange_chars ( self ) :
def test_strange_chars ( self ) :
jsi = JSInterpreter ( ' function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; } ' )
self . _test ( ' function $_xY1 ($_axY1) { var $_axY2 = $_axY1 + 1; return $_axY2; } ' ,
self . assertEqual ( jsi . call_function ( ' $_xY1 ' , 20 ) , 21 )
21 , args = [ 20 ] , func = ' $_xY1 ' )
def test_operators ( self ) :
def test_operators ( self ) :
jsi = JSInterpreter ( ' function f() { return 1 << 5;} ' )
self . _test ( ' function f() { return 1 << 5;} ' , 32 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 32 )
self . _test ( ' function f() { return 2 ** 5} ' , 32 )
self . _test ( ' function f() { return 19 & 21;} ' , 17 )
jsi = JSInterpreter ( ' function f() { return 2 ** 5} ' )
self . _test ( ' function f() { return 11 >> 2;} ' , 2 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 32 )
self . _test ( ' function f() { return []? 2+3: 4;} ' , 5 )
self . _test ( ' function f() { return 1 == 2} ' , False )
jsi = JSInterpreter ( ' function f() { return 19 & 21;} ' )
self . _test ( ' function f() { return 0 && 1 || 2;} ' , 2 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 17 )
self . _test ( ' function f() { return 0 ?? 42;} ' , 0 )
self . _test ( ' function f() { return " life, the universe and everything " < 42;} ' , False )
jsi = JSInterpreter ( ' function f() { return 11 >> 2;} ' )
# https://github.com/ytdl-org/youtube-dl/issues/32815
self . assertEqual ( jsi . call_function ( ' f ' ) , 2 )
self . _test ( ' function f() { return 0 - 7 * - 6;} ' , 42 )
jsi = JSInterpreter ( ' function f() { return []? 2+3: 4;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 5 )
jsi = JSInterpreter ( ' function f() { return 1 == 2} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , False )
jsi = JSInterpreter ( ' function f() { return 0 && 1 || 2;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 2 )
jsi = JSInterpreter ( ' function f() { return 0 ?? 42;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 0 )
jsi = JSInterpreter ( ' function f() { return " life, the universe and everything " < 42;} ' )
self . assertFalse ( jsi . call_function ( ' f ' ) )
def test_array_access ( self ) :
def test_array_access ( self ) :
jsi = JSInterpreter ( ' function f() { var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2.0] = 7; return x;} ' )
self . _test ( ' function f() { var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2.0] = 7; return x;} ' , [ 5 , 2 , 7 ] )
self . assertEqual ( jsi . call_function ( ' f ' ) , [ 5 , 2 , 7 ] )
def test_parens ( self ) :
def test_parens ( self ) :
jsi = JSInterpreter ( ' function f() { return (1) + (2) * ((( (( (((((3)))))) )) ));} ' )
self . _test ( ' function f() { return (1) + (2) * ((( (( (((((3)))))) )) ));} ' , 7 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 7 )
self . _test ( ' function f() { return (1 + 2) * 3;} ' , 9 )
jsi = JSInterpreter ( ' function f() { return (1 + 2) * 3;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 9 )
def test_quotes ( self ) :
def test_quotes ( self ) :
jsi = JSInterpreter ( r ' function f() { return " a \ " \\ ( " } ' )
self . _test ( r ' function f() { return " a \ " \\ ( " } ' , r ' a " \ ( ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , r ' a " \ ( ' )
def test_assignments ( self ) :
def test_assignments ( self ) :
jsi = JSInterpreter ( ' function f() { var x = 20; x = 30 + 1; return x;} ' )
self . _test ( ' function f() { var x = 20; x = 30 + 1; return x;} ' , 31 )
self . assertEqual ( jsi . call_function ( ' f ' ) , 31 )
self . _test ( ' function f() { var x = 20; x += 30 + 1; return x;} ' , 51 )
self . _test ( ' function f() { var x = 20; x -= 30 + 1; return x;} ' , - 11 )
jsi = JSInterpreter ( ' function f() { var x = 20; x += 30 + 1; return x;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 51 )
jsi = JSInterpreter ( ' function f() { var x = 20; x -= 30 + 1; return x;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , - 11 )
@unittest.skip ( ' Not yet fully implemented ' )
def test_comments ( self ) :
def test_comments ( self ) :
' Skipping: Not yet fully implemented '
self . _test ( '''
return
function f ( ) {
jsi = JSInterpreter ( '''
var x = / * 1 + * / 2 ;
function x ( ) {
var y = / * 30
var x = / * 1 + * / 2 ;
* 40 * / 50 ;
var y = / * 30
return x + y ;
* 40 * / 50 ;
}
return x + y ;
''' , 52)
}
''' )
self . _test ( '''
self . assertEqual ( jsi . call_function ( ' x ' ) , 52 )
function f ( ) {
var x = " /* " ;
jsi = JSInterpreter ( '''
var y = 1 / * comment * / + 2 ;
function f ( ) {
return y ;
var x = " /* " ;
}
var y = 1 / * comment * / + 2 ;
''' , 3)
return y ;
}
''' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 3 )
def test_precedence ( self ) :
def test_precedence ( self ) :
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
var a = [ 10 , 20 , 30 , 40 , 50 ] ;
var a = [ 10 , 20 , 30 , 40 , 50 ] ;
var b = 6 ;
var b = 6 ;
a [ 0 ] = a [ b % a . length ] ;
a [ 0 ] = a [ b % a . length ] ;
return a ;
return a ;
} ''' )
}
self . assertEqual ( jsi . call_function ( ' x ' ) , [ 20 , 20 , 30 , 40 , 50 ] )
''' , [20, 20, 30, 40, 50] )
def test_builtins ( self ) :
def test_builtins ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return NaN } ' , NaN )
function x ( ) { return NaN }
''' )
self . assertTrue ( math . isnan ( jsi . call_function ( ' x ' ) ) )
def test_Date ( self ) :
def test_Date ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return new Date( " Wednesday 31 December 1969 18:01:26 MDT " ) - 0; } ' , 86000 )
function x ( dt ) { return new Date ( dt ) - 0 ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' , ' Wednesday 31 December 1969 18:01:26 MDT ' ) , 86000 )
jsi = JSInterpreter ( ' function f(dt) { return new Date(dt) - 0; } ' )
# date format m/d/y
# date format m/d/y
self . assertEqual ( jsi . call_function ( ' x ' , ' 12/31/1969 18:01:26 MDT ' ) , 86000 )
self . _test ( jsi , 86000 , args = [ ' 12/31/1969 18:01:26 MDT ' ] )
# epoch 0
# epoch 0
self . assertEqual( jsi . call_function ( ' x ' , ' 1 January 1970 00:00:00 UTC ' ) , 0 )
self . _test( jsi , 0 , args = [ ' 1 January 1970 00:00:00 UTC ' ] )
def test_call ( self ) :
def test_call ( self ) :
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
@ -206,179 +158,115 @@ class TestJSInterpreter(unittest.TestCase):
function y ( a ) { return x ( ) + ( a ? a : 0 ) ; }
function y ( a ) { return x ( ) + ( a ? a : 0 ) ; }
function z ( ) { return y ( 3 ) ; }
function z ( ) { return y ( 3 ) ; }
''' )
''' )
self . assertEqual( jsi . call_function ( ' z ' ) , 5 )
self . _test( jsi , 5 , func = ' z ' )
self . assertEqual( jsi . call_function ( ' y ' ) , 2 )
self . _test( jsi , 2 , func = ' y ' )
def test_if ( self ) :
def test_if ( self ) :
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
let a = 9 ;
let a = 9 ;
if ( 0 == 0 ) { a + + }
if ( 0 == 0 ) { a + + }
return a
return a
} ''' )
}
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
''' , 10 )
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
if ( 0 == 0 ) { return 10 }
if ( 0 == 0 ) { return 10 }
} ''' )
}
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
''' , 10 )
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
if ( 0 != 0 ) { return 1 }
if ( 0 != 0 ) { return 1 }
else { return 10 }
else { return 10 }
} ''' )
}
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
''' , 10)
""" # Unsupported
jsi = JSInterpreter ( '''
function x ( ) {
if ( 0 != 0 ) return 1 ;
else { return 10 }
} ''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
"""
def test_elseif ( self ) :
def test_elseif ( self ) :
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
if ( 0 != 0 ) { return 1 }
if ( 0 != 0 ) { return 1 }
else if ( 1 == 0 ) { return 2 }
else if ( 1 == 0 ) { return 2 }
else { return 10 }
else { return 10 }
} ''' )
}
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
''' , 10)
""" # Unsupported
jsi = JSInterpreter ( '''
function x ( ) {
if ( 0 != 0 ) return 1 ;
else if ( 1 == 0 ) { return 2 }
else { return 10 }
} ''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
# etc
"""
def test_for_loop ( self ) :
def test_for_loop ( self ) :
# function x() { a=0; for (i=0; i-10; i++) {a++} a }
self . _test ( ' function f() { a=0; for (i=0; i-10; i++) { a++} return a } ' , 10 )
jsi = JSInterpreter ( '''
function x ( ) { a = 0 ; for ( i = 0 ; i - 10 ; i + + ) { a + + } return a }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
def test_while_loop ( self ) :
def test_while_loop ( self ) :
# function x() { a=0; while (a<10) {a++} a }
self . _test ( ' function f() { a=0; while (a<10) { a++} return a } ' , 10 )
jsi = JSInterpreter ( '''
function x ( ) { a = 0 ; while ( a < 10 ) { a + + } return a }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
def test_switch ( self ) :
def test_switch ( self ) :
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
function x ( f ) { switch ( f ) {
function f ( x ) { switch ( x ) {
case 1 : f + = 1 ;
case 1 : x + = 1 ;
case 2 : f + = 2 ;
case 2 : x + = 2 ;
case 3 : f + = 3 ; break ;
case 3 : x + = 3 ; break ;
case 4 : f + = 4 ;
case 4 : x + = 4 ;
default : f = 0 ;
default : x = 0 ;
} return f }
} return x }
''' )
''' )
self . assertEqual( jsi . call_function ( ' x ' , 1 ) , 7 )
self . _test( jsi , 7 , args = [ 1 ] )
self . assertEqual( jsi . call_function ( ' x ' , 3 ) , 6 )
self . _test( jsi , 6 , args = [ 3 ] )
self . assertEqual( jsi . call_function ( ' x ' , 5 ) , 0 )
self . _test( jsi , 0 , args = [ 5 ] )
def test_switch_default ( self ) :
def test_switch_default ( self ) :
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
function x ( f ) { switch ( f ) {
function f ( x ) { switch ( x ) {
case 2 : f + = 2 ;
case 2 : x + = 2 ;
default : f - = 1 ;
default : x - = 1 ;
case 5 :
case 5 :
case 6 : f + = 6 ;
case 6 : x + = 6 ;
case 0 : break ;
case 0 : break ;
case 1 : f + = 1 ;
case 1 : x + = 1 ;
} return f }
} return x }
''' )
''' )
self . assertEqual( jsi . call_function ( ' x ' , 1 ) , 2 )
self . _test( jsi , 2 , args = [ 1 ] )
self . assertEqual( jsi . call_function ( ' x ' , 5 ) , 11 )
self . _test( jsi , 11 , args = [ 5 ] )
self . assertEqual( jsi . call_function ( ' x ' , 9 ) , 14 )
self . _test( jsi , 14 , args = [ 9 ] )
def test_try ( self ) :
def test_try ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { try { return 10} catch(e) { return 5} } ' , 10 )
function x ( ) { try { return 10 } catch ( e ) { return 5 } }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 10 )
def test_catch ( self ) :
def test_catch ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { try { throw 10} catch(e) { return 5} } ' , 5 )
function x ( ) { try { throw 10 } catch ( e ) { return 5 } }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 5 )
def test_finally ( self ) :
def test_finally ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { try { throw 10} finally { return 42} } ' , 42 )
function x ( ) { try { throw 10 } finally { return 42 } }
self . _test ( ' function f() { try { throw 10} catch(e) { return 5} finally { return 42} } ' , 42 )
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
jsi = JSInterpreter ( '''
function x ( ) { try { throw 10 } catch ( e ) { return 5 } finally { return 42 } }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
def test_nested_try ( self ) :
def test_nested_try ( self ) :
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) { try {
function f ( ) { try {
try { throw 10 } finally { throw 42 }
try { throw 10 } finally { throw 42 }
} catch ( e ) { return 5 } }
} catch ( e ) { return 5 } }
''' )
''' , 5)
self . assertEqual ( jsi . call_function ( ' x ' ) , 5 )
def test_for_loop_continue ( self ) :
def test_for_loop_continue ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { a=0; for (i=0; i-10; i++) { continue; a++ } return a } ' , 0 )
function x ( ) { a = 0 ; for ( i = 0 ; i - 10 ; i + + ) { continue ; a + + } return a }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 0 )
def test_for_loop_break ( self ) :
def test_for_loop_break ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { a=0; for (i=0; i-10; i++) { break; a++ } return a } ' , 0 )
function x ( ) { a = 0 ; for ( i = 0 ; i - 10 ; i + + ) { break ; a + + } return a }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 0 )
def test_for_loop_try ( self ) :
def test_for_loop_try ( self ) :
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) {
function f ( ) {
for ( i = 0 ; i - 10 ; i + + ) { try { if ( i == 5 ) throw i } catch { return 10 } finally { break } } ;
for ( i = 0 ; i - 10 ; i + + ) { try { if ( i == 5 ) throw i } catch { return 10 } finally { break } } ;
return 42 }
return 42 }
''' )
''' , 42)
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
def test_literal_list ( self ) :
def test_literal_list ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return [1, 2, " asdf " , [5, 6, 7]][3] } ' , [ 5 , 6 , 7 ] )
function x ( ) { return [ 1 , 2 , " asdf " , [ 5 , 6 , 7 ] ] [ 3 ] }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ 5 , 6 , 7 ] )
def test_comma ( self ) :
def test_comma ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { a=5; a -= 1, a+=3; return a } ' , 7 )
function x ( ) { a = 5 ; a - = 1 , a + = 3 ; return a }
self . _test ( ' function f() { a=5; return (a -= 1, a+=3, a); } ' , 7 )
''' )
self . _test ( ' function f() { return (l=[0,1,2,3], function(a, b) { return a+b})((l[1], l[2]), l[3]) } ' , 5 )
self . assertEqual ( jsi . call_function ( ' x ' ) , 7 )
jsi = JSInterpreter ( '''
function x ( ) { a = 5 ; return ( a - = 1 , a + = 3 , a ) ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 7 )
jsi = JSInterpreter ( '''
function x ( ) { return ( l = [ 0 , 1 , 2 , 3 ] , function ( a , b ) { return a + b } ) ( ( l [ 1 ] , l [ 2 ] ) , l [ 3 ] ) }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 5 )
def test_void ( self ) :
def test_void ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return void 42; } ' , None )
function x ( ) { return void 42 ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , None )
def test_return_function ( self ) :
def test_return_function ( self ) :
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
@ -387,110 +275,60 @@ class TestJSInterpreter(unittest.TestCase):
self . assertEqual ( jsi . call_function ( ' x ' ) ( [ ] ) , 1 )
self . assertEqual ( jsi . call_function ( ' x ' ) ( [ ] ) , 1 )
def test_null ( self ) :
def test_null ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return null; } ' , None )
function x ( ) { return null ; }
self . _test ( ' function f() { return [null > 0, null < 0, null == 0, null === 0]; } ' ,
''' )
[ False , False , False , False ] )
self . assertIs ( jsi . call_function ( ' x ' ) , None )
self . _test ( ' function f() { return [null >= 0, null <= 0]; } ' , [ True , True ] )
jsi = JSInterpreter ( '''
function x ( ) { return [ null > 0 , null < 0 , null == 0 , null == = 0 ] ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , False , False , False ] )
jsi = JSInterpreter ( '''
function x ( ) { return [ null > = 0 , null < = 0 ] ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ True , True ] )
def test_undefined ( self ) :
def test_undefined ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return undefined === undefined; } ' , True )
function x ( ) { return undefined == = undefined ; }
self . _test ( ' function f() { return undefined; } ' , JS_Undefined )
''' )
self . _test ( ' function f() { return undefined ?? 42; } ' , 42 )
self . assertTrue ( jsi . call_function ( ' x ' ) )
self . _test ( ' function f() { let v; return v; } ' , JS_Undefined )
self . _test ( ' function f() { let v; return v**0; } ' , 1 )
jsi = JSInterpreter ( '''
self . _test ( ' function f() { let v; return [v>42, v<=42, v&&42, 42&&v]; } ' ,
function x ( ) { return undefined ; }
[ False , False , JS_Undefined , JS_Undefined ] )
''' )
self . assertIs ( jsi . call_function ( ' x ' ) , JS_Undefined )
self . _test ( '''
function f ( ) { return [
jsi = JSInterpreter ( '''
undefined == = undefined ,
function x ( ) { let v ; return v ; }
undefined == undefined ,
''' )
undefined == null
self . assertIs ( jsi . call_function ( ' x ' ) , JS_Undefined )
] ; }
''' , [True] * 3)
jsi = JSInterpreter ( '''
self . _test ( '''
function x ( ) { return [ undefined == = undefined , undefined == undefined , undefined < undefined , undefined > undefined ] ; }
function f ( ) { return [
''' )
undefined < undefined ,
self . assertEqual ( jsi . call_function ( ' x ' ) , [ True , True , False , False ] )
undefined > undefined ,
undefined == = 0 ,
jsi = JSInterpreter ( '''
undefined == 0 ,
function x ( ) { return [ undefined == = 0 , undefined == 0 , undefined < 0 , undefined > 0 ] ; }
undefined < 0 ,
''' )
undefined > 0 ,
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , False , False , False ] )
undefined > = 0 ,
undefined < = 0 ,
jsi = JSInterpreter ( '''
undefined > null ,
function x ( ) { return [ undefined > = 0 , undefined < = 0 ] ; }
undefined < null ,
''' )
undefined == = null
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , False ] )
] ; }
''' , [False] * 11)
jsi = JSInterpreter ( '''
function x ( ) { return [ undefined > null , undefined < null , undefined == null , undefined == = null ] ; }
jsi = JSInterpreter ( '''
''' )
function x ( ) { let v ; return [ 42 + v , v + 42 , v * * 42 , 42 * * v , 0 * * v ] ; }
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , False , True , False ] )
jsi = JSInterpreter ( '''
function x ( ) { return [ undefined == = null , undefined == null , undefined < null , undefined > null ] ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , True , False , False ] )
jsi = JSInterpreter ( '''
function x ( ) { let v ; return [ 42 + v , v + 42 , v * * 42 , 42 * * v , 0 * * v ] ; }
''' )
''' )
for y in jsi . call_function ( ' x ' ) :
for y in jsi . call_function ( ' x ' ) :
self . assertTrue ( math . isnan ( y ) )
self . assertTrue ( math . isnan ( y ) )
jsi = JSInterpreter ( '''
function x ( ) { let v ; return v * * 0 ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 1 )
jsi = JSInterpreter ( '''
function x ( ) { let v ; return [ v > 42 , v < = 42 , v & & 42 , 42 & & v ] ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ False , False , JS_Undefined , JS_Undefined ] )
jsi = JSInterpreter ( ' function x() { return undefined ?? 42; } ' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
def test_object ( self ) :
def test_object ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { return {} ; } ' , { } )
function x ( ) { return { } ; }
self . _test ( ' function f() { let a = { m1: 42, m2: 0 }; return [a[ " m1 " ], a.m2]; } ' , [ 42 , 0 ] )
''' )
self . _test ( ' function f() { let a; return a?.qq; } ' , JS_Undefined )
self . assertEqual ( jsi . call_function ( ' x ' ) , { } )
self . _test ( ' function f() { let a = { m1: 42, m2: 0 }; return a?.qq; } ' , JS_Undefined )
jsi = JSInterpreter ( '''
function x ( ) { let a = { m1 : 42 , m2 : 0 } ; return [ a [ " m1 " ] , a . m2 ] ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , [ 42 , 0 ] )
jsi = JSInterpreter ( '''
function x ( ) { let a ; return a ? . qq ; }
''' )
self . assertIs ( jsi . call_function ( ' x ' ) , JS_Undefined )
jsi = JSInterpreter ( '''
function x ( ) { let a = { m1 : 42 , m2 : 0 } ; return a ? . qq ; }
''' )
self . assertIs ( jsi . call_function ( ' x ' ) , JS_Undefined )
def test_regex ( self ) :
def test_regex ( self ) :
jsi = JSInterpreter ( '''
self . _test ( ' function f() { let a=/,,[/,913,/](,)}/; } ' , None )
function x ( ) { let a = / , , [ / , 913 , / ] ( , ) } / ; }
''' )
self . assertIs ( jsi . call_function ( ' x ' ) , None )
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
function x ( ) { let a = / , , [ / , 913 , / ] ( , ) } / ; " " . replace ( a , " " ) ; return a ; }
function x ( ) { let a = / , , [ / , 913 , / ] ( , ) } / ; " " . replace ( a , " " ) ; return a ; }
''' )
''' )
attrs = set ( ( ' findall ' , ' finditer ' , ' match ' , ' scanner ' , ' search ' ,
attrs = set ( ( ' findall ' , ' finditer ' , ' match ' , ' scanner ' , ' search ' ,
' split ' , ' sub ' , ' subn ' ) )
' split ' , ' sub ' , ' subn ' ) )
@ -500,94 +338,92 @@ class TestJSInterpreter(unittest.TestCase):
self . assertSetEqual ( set ( dir ( jsi . call_function ( ' x ' ) ) ) & attrs , attrs )
self . assertSetEqual ( set ( dir ( jsi . call_function ( ' x ' ) ) ) & attrs , attrs )
jsi = JSInterpreter ( '''
jsi = JSInterpreter ( '''
function x ( ) { let a = / , , [ / , 913 , / ] ( , ) } / i ; return a ; }
function x ( ) { let a = / , , [ / , 913 , / ] ( , ) } / i ; return a ; }
''' )
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) . flags & ~ re . U , re . I )
self . assertEqual ( jsi . call_function ( ' x ' ) . flags & ~ re . U , re . I )
jsi = JSInterpreter ( r '''
jsi = JSInterpreter ( r ' function f() { let a=/,][} " ,],()}( \ [)/; return a; } ' )
function x ( ) { let a = " data-name " . replace ( " data- " , " " ) ; return a }
self . assertEqual ( jsi . call_function ( ' f ' ) . pattern , r ' ,][} " ,],()}( \ [) ' )
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , ' name ' )
jsi = JSInterpreter ( r '''
function x ( ) { let a = " data-name " . replace ( new RegExp ( " ^.+- " ) , " " ) ; return a ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , ' name ' )
jsi = JSInterpreter ( r '''
function x ( ) { let a = " data-name " . replace ( / ^ . + - / , " " ) ; return a ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , ' name ' )
jsi = JSInterpreter ( r '''
function x ( ) { let a = " data-name " . replace ( / a / g , " o " ) ; return a ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , ' doto-nome ' )
jsi = JSInterpreter ( r '''
function x ( ) { let a = " data-name " . replaceAll ( " a " , " o " ) ; return a ; }
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) , ' doto-nome ' )
jsi = JSInterpreter ( r '''
jsi = JSInterpreter ( r ' function f() { let a=[/[) \\ ]/]; return a[0]; } ' )
function x ( ) { let a = [ / [ ) \\] / ] ; return a [ 0 ] ; }
self . assertEqual ( jsi . call_function ( ' f ' ) . pattern , r ' [) \\ ] ' )
''' )
self . assertEqual ( jsi . call_function ( ' x ' ) . pattern , r ' [) \\ ] ' )
""" # fails
def test_replace ( self ) :
jsi = JSInterpreter ( r '''
self . _test ( ' function f() { let a= " data-name " .replace( " data- " , " " ); return a } ' ,
function x ( ) { let a = 100 ; a / = / [ 0 - 9 ] + / . exec ( ' divide by 20 today ' ) [ 0 ] ; }
' name ' )
''' )
self . _test ( ' function f() { let a= " data-name " .replace(new RegExp( " ^.+- " ), " " ); return a; } ' ,
self . assertEqual ( jsi . call_function ( ' x ' ) , 5 )
' name ' )
"""
self . _test ( ' function f() { let a= " data-name " .replace(/^.+-/, " " ); return a; } ' ,
' name ' )
self . _test ( ' function f() { let a= " data-name " .replace(/a/g, " o " ); return a; } ' ,
' doto-nome ' )
self . _test ( ' function f() { let a= " data-name " .replaceAll( " a " , " o " ); return a; } ' ,
' doto-nome ' )
def test_char_code_at ( self ) :
def test_char_code_at ( self ) :
jsi = JSInterpreter ( ' function x(i) { return " test " .charCodeAt(i)} ' )
jsi = JSInterpreter ( ' function f(i) { return " test " .charCodeAt(i)} ' )
self . assertEqual ( jsi . call_function ( ' x ' , 0 ) , 116 )
self . _test ( jsi , 116 , args = [ 0 ] )
self . assertEqual ( jsi . call_function ( ' x ' , 1 ) , 101 )
self . _test ( jsi , 101 , args = [ 1 ] )
self . assertEqual( jsi . call_function ( ' x ' , 2 ) , 115 )
self . _test ( jsi , 115 , args = [ 2 ] )
self . assertEqual( jsi . call_function ( ' x ' , 3 ) , 116 )
self . _test ( jsi , 116 , args = [ 3 ] )
self . assertEqual( jsi . call_function ( ' x ' , 4 ) , None )
self . _test( jsi , None , args = [ 4 ] )
self . assertEqual( jsi . call_function ( ' x ' , ' not_a_number ' ) , 116 )
self . _test( jsi , 116 , args = [ ' not_a_number ' ] )
def test_bitwise_operators_overflow ( self ) :
def test_bitwise_operators_overflow ( self ) :
jsi = JSInterpreter ( ' function x() { return -524999584 << 5} ' )
self . _test ( ' function f() { return -524999584 << 5} ' , 379882496 )
self . assertEqual ( jsi . call_function ( ' x ' ) , 379882496 )
self . _test ( ' function f() { return 1236566549 << 5} ' , 915423904 )
jsi = JSInterpreter ( ' function x() { return 1236566549 << 5} ' )
def test_bitwise_operators_typecast ( self ) :
self . assertEqual ( jsi . call_function ( ' x ' ) , 915423904 )
# madness
self . _test ( ' function f() { return null << 5} ' , 0 )
def test_bitwise_operators_madness ( self ) :
self . _test ( ' function f() { return undefined >> 5} ' , 0 )
jsi = JSInterpreter ( ' function x() { return null << 5} ' )
self . _test ( ' function f() { return 42 << NaN} ' , 42 )
self . assertEqual ( jsi . call_function ( ' x ' ) , 0 )
self . _test ( ' function f() { return 42 << Infinity} ' , 42 )
jsi = JSInterpreter ( ' function x() { return undefined >> 5} ' )
def test_negative ( self ) :
self . assertEqual ( jsi . call_function ( ' x ' ) , 0 )
self . _test ( ' function f() { return 2 * -2.0 ;} ' , - 4 )
self . _test ( ' function f() { return 2 - - -2 ;} ' , 0 )
jsi = JSInterpreter ( ' function x() { return 42 << NaN} ' )
self . _test ( ' function f() { return 2 - - - -2 ;} ' , 4 )
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
self . _test ( ' function f() { return 2 - + + - -2;} ' , 0 )
self . _test ( ' function f() { return 2 + - + - -2;} ' , 0 )
jsi = JSInterpreter ( ' function x() { return 42 << Infinity} ' )
self . assertEqual ( jsi . call_function ( ' x ' ) , 42 )
def test_32066 ( self ) :
def test_32066 ( self ) :
jsi = JSInterpreter ( " function x() { return Math.pow(3, 5) + new Date( ' 1970-01-01T08:01:42.000+08:00 ' ) / 1000 * -239 - -24205;} " )
self . _test (
self . assertEqual ( jsi . call_function ( ' x ' ) , 70 )
" function f() { return Math.pow(3, 5) + new Date( ' 1970-01-01T08:01:42.000+08:00 ' ) / 1000 * -239 - -24205;} " ,
70 )
def test_unary_operators ( self ) :
jsi = JSInterpreter ( ' function f() { return 2 - - - 2;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 0 )
jsi = JSInterpreter ( ' function f() { return 2 + - + - - 2;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 0 )
# https://github.com/ytdl-org/youtube-dl/issues/32815
jsi = JSInterpreter ( ' function f() { return 0 - 7 * - 6;} ' )
self . assertEqual ( jsi . call_function ( ' f ' ) , 42 )
""" # fails so far
@unittest.skip ( ' Not yet working ' )
def test_packed ( self ) :
def test_packed ( self ) :
jsi = JSInterpreter ( ''' function x(p,a,c,k,e,d) { while(c--)if(k[c])p=p.replace(new RegExp( ' \\ b ' +c.toString(a)+ ' \\ b ' , ' g ' ),k[c]);return p} ''' )
self . _test (
self . assertEqual ( jsi . call_function ( ' x ' , ''' h 7=g( " 1j " );7.7h( { 7g:[ { 33: " w://7f-7e-7d-7c.v.7b/7a/79/78/77/76.74?t=73&s=2s&e=72&f=2t&71=70.0.0.1&6z=6y&6x=6w " }],6v: " w://32.v.u/6u.31 " ,16: " r % " ,15: " r % " ,6t: " 6s " ,6r: " " ,6q: " l " ,6p: " l " ,6o: " 6n " ,6m: \' 6l \' ,6k: " 6j " ,9:[ { 33: " /2u?b=6i&n=50&6h=w://32.v.u/6g.31 " ,6f: " 6e " }],1y: { 6d:1,6c: \' #6b \' ,6a: \' #69 \' ,68: " 67 " ,66:30,65:r,}, " 64 " : { 63: " % 62 2m % m %61% 5z % 5y %5x .u % 5w % 5v %5u .2y % 22 2k % m %1o % 22 5t % m %1o % 22 5s % m %1o % 22 2j % m %5r % 22 16 % m % 5q % 22 15 % m % 5p % 22 5o % 2z % 5n % 5m % 2z " ,5l: " w://v.u/d/1k/5k.2y " ,5j:[]}, \' 5i \' : { " 5h " : " 5g " },5f: " 5e " ,5d: " w://v.u " ,5c: {} ,5b:l,1x:[0.25,0.50,0.75,1,1.25,1.5,2]});h 1m,1n,5a;h 59=0,58=0;h 7=g( " 1j " );h 2x=0,57=0,56=0;$.55( { 54: { \' 53-52 \' : \' 2i-51 \' }});7.j( \' 4z \' ,6(x) { c(5>0&&x.1l>=5&&1n!=1) { 1n=1;$( \' q.4y \' ).4x( \' 4w \' )}});7.j( \' 13 \' ,6(x) { 2x=x.1l});7.j( \' 2g \' ,6(x) { 2w(x)});7.j( \' 4v \' ,6() { $( \' q.2v \' ).4u()});6 2w(x) { $( \' q.2v \' ).4t();c(1m)19;1m=1;17=0;c(4s.4r===l) { 17=1}$.4q( \' /2u?b=4p&2l=1k&4o=2t-4n-4m-2s-4l&4k=&4j=&4i=&17= \' +17,6(2r) { $( \' #4h \' ).4g(2r)});$( \' .3-8-4f-4e:4d( " 4c " ) \' ).2h(6(e) { 2q();g().4b(0);g().4a(l)});6 2q() { h $14=$( " <q /> " ).2p( { 1l: " 49 " ,16: " r % " ,15: " r % " ,48:0,2n:0,2o:47,46: " 45(10 % , 10 % , 10 % , 0.4) " , " 44-43 " : " 42 " });$( " <41 /> " ).2p( { 16: " 60 % " ,15: " 60 % " ,2o:40, " 3z-2n " : " 3y " }).3x( { \' 2m \' : \' /?b=3w&2l=1k \' , \' 2k \' : \' 0 \' , \' 2j \' : \' 2i \' }).2f($14);$14.2h(6() { $(3v).3u();g().2g()});$14.2f($( \' #1j \' ))}g().13(0);}6 3t() { h 9=7.1b(2e);2d.2c(9);c(9.n>1) { 1r(i=0;i<9.n;i++) { c(9[i].1a==2e) { 2d.2c( \' !!= \' +i);7.1p(i)}}}}7.j( \' 3s \' ,6() { g().1h( " /2a/3r.29 " , " 3q 10 28 " ,6() { g().13(g().27()+10)}, " 2b " );$( " q[26=2b] " ).23().21( \' .3-20-1z \' );g().1h( " /2a/3p.29 " , " 3o 10 28 " ,6() { h 12=g().27()-10;c(12<0)12=0;g().13(12)}, " 24 " );$( " q[26=24] " ).23().21( \' .3-20-1z \' );});6 1i() {} 7.j( \' 3n \' ,6() { 1i()});7.j( \' 3m \' ,6() { 1i()});7.j( " k " ,6(y) { h 9=7.1b();c(9.n<2)19;$( \' .3-8-3l-3k \' ).3j(6() { $( \' #3-8-a-k \' ).1e( \' 3-8-a-z \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' 11 \' )});7.1h( " /3i/3h.3g " , " 3f 3e " ,6() { $( \' .3-1w \' ).3d( \' 3-8-1v \' );$( \' .3-8-1y, .3-8-1x \' ).p( \' o-1g \' , \' 11 \' );c($( \' .3-1w \' ).3c( \' 3-8-1v \' )) { $( \' .3-a-k \' ).p( \' o-1g \' , \' l \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' l \' );$( \' .3-8-a \' ).1e( \' 3-8-a-z \' );$( \' .3-8-a:1u \' ).3b( \' 3-8-a-z \' )}3a { $( \' .3-a-k \' ).p( \' o-1g \' , \' 11 \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' 11 \' );$( \' .3-8-a:1u \' ).1e( \' 3-8-a-z \' )}}, " 39 " );7.j( " 38 " ,6(y) { 1d.37( \' 1c \' ,y.9[y.36].1a)});c(1d.1t( \' 1c \' )) { 35( " 1s(1d.1t( \' 1c \' )); " ,34)}});h 18;6 1s(1q) { h 9=7.1b();c(9.n>1) { 1r(i=0;i<9.n;i++) { c(9[i].1a==1q) { c(i==18) {19} 18=i;7.1p(i)}}}} ' ,36,270, ' |||jw|||function|player|settings|tracks|submenu||if||||jwplayer|var||on|audioTracks|true|3D|length|aria|attr|div|100|||sx|filemoon|https||event|active||false|tt|seek|dd|height|width|adb|current_audio|return|name|getAudioTracks|default_audio|localStorage|removeClass|expanded|checked|addButton|callMeMaybe|vplayer|0fxcyc2ajhp1|position|vvplay|vvad|220|setCurrentAudioTrack|audio_name|for|audio_set|getItem|last|open|controls|playbackRates|captions|rewind|icon|insertAfter||detach|ff00||button|getPosition|sec|png|player8|ff11|log|console|track_name|appendTo|play|click|no|scrolling|frameborder|file_code|src|top|zIndex|css|showCCform|data|1662367683|383371|dl|video_ad|doPlay|prevt|mp4|3E||jpg|thumbs|file|300|setTimeout|currentTrack|setItem|audioTrackChanged|dualSound|else|addClass|hasClass|toggleClass|Track|Audio|svg|dualy|images|mousedown|buttons|topbar|playAttemptFailed|beforePlay|Rewind|fr|Forward|ff|ready|set_audio_track|remove|this|upload_srt|prop|50px|margin|1000001|iframe|center|align|text|rgba|background|1000000|left|absolute|pause|setCurrentCaptions|Upload|contains|item|content|html|fviews|referer|prem|embed|3e57249ef633e0d03bf76ceb8d8a4b65|216|83|hash|view|get|TokenZir|window|hide|show|complete|slow|fadeIn|video_ad_fadein|time||cache|Cache|Content|headers|ajaxSetup|v2done|tott|vastdone2|vastdone1|vvbefore|playbackRateControls|cast|aboutlink|FileMoon|abouttext|UHD|1870|qualityLabels|sites|GNOME_POWER|link|2Fiframe|3C|allowfullscreen|22360|22640|22no|marginheight|marginwidth|2FGNOME_POWER|2F0fxcyc2ajhp1|2Fe|2Ffilemoon|2F|3A||22https|3Ciframe|code|sharing|fontOpacity|backgroundOpacity|Tahoma|fontFamily|303030|backgroundColor|FFFFFF|color|userFontScale|thumbnails|kind|0fxcyc2ajhp10000|url|get_slides|start|startparam|none|preload|html5|primary|hlshtml|androidhls|duration|uniform|stretching|0fxcyc2ajhp1_xt|image|2048|sp|6871|asn|127|srv|43200|_g3XlBcu2lmD9oDexD2NLWSmah2Nu3XcDrl93m9PwXY|m3u8||master|0fxcyc2ajhp1_x|00076|01|hls2|to|s01|delivery|storage|moon|sources|setup ''' . split ( ' | ' ) ) )
''' function f(p,a,c,k,e,d) { while(c--)if(k[c])p=p.replace(new RegExp( ' \\ b ' +c.toString(a)+ ' \\ b ' , ' g ' ),k[c]);return p} ''' ,
"""
''' h 7=g( " 1j " );7.7h( { 7g:[ { 33: " w://7f-7e-7d-7c.v.7b/7a/79/78/77/76.74?t=73&s=2s&e=72&f=2t&71=70.0.0.1&6z=6y&6x=6w " }],6v: " w://32.v.u/6u.31 " ,16: " r % " ,15: " r % " ,6t: " 6s " ,6r: " " ,6q: " l " ,6p: " l " ,6o: " 6n " ,6m: \' 6l \' ,6k: " 6j " ,9:[ { 33: " /2u?b=6i&n=50&6h=w://32.v.u/6g.31 " ,6f: " 6e " }],1y: { 6d:1,6c: \' #6b \' ,6a: \' #69 \' ,68: " 67 " ,66:30,65:r,}, " 64 " : { 63: " % 62 2m % m %61% 5z % 5y %5x .u % 5w % 5v %5u .2y % 22 2k % m %1o % 22 5t % m %1o % 22 5s % m %1o % 22 2j % m %5r % 22 16 % m % 5q % 22 15 % m % 5p % 22 5o % 2z % 5n % 5m % 2z " ,5l: " w://v.u/d/1k/5k.2y " ,5j:[]}, \' 5i \' : { " 5h " : " 5g " },5f: " 5e " ,5d: " w://v.u " ,5c: {} ,5b:l,1x:[0.25,0.50,0.75,1,1.25,1.5,2]});h 1m,1n,5a;h 59=0,58=0;h 7=g( " 1j " );h 2x=0,57=0,56=0;$.55( { 54: { \' 53-52 \' : \' 2i-51 \' }});7.j( \' 4z \' ,6(x) { c(5>0&&x.1l>=5&&1n!=1) { 1n=1;$( \' q.4y \' ).4x( \' 4w \' )}});7.j( \' 13 \' ,6(x) { 2x=x.1l});7.j( \' 2g \' ,6(x) { 2w(x)});7.j( \' 4v \' ,6() { $( \' q.2v \' ).4u()});6 2w(x) { $( \' q.2v \' ).4t();c(1m)19;1m=1;17=0;c(4s.4r===l) { 17=1}$.4q( \' /2u?b=4p&2l=1k&4o=2t-4n-4m-2s-4l&4k=&4j=&4i=&17= \' +17,6(2r) { $( \' #4h \' ).4g(2r)});$( \' .3-8-4f-4e:4d( " 4c " ) \' ).2h(6(e) { 2q();g().4b(0);g().4a(l)});6 2q() { h $14=$( " <q /> " ).2p( { 1l: " 49 " ,16: " r % " ,15: " r % " ,48:0,2n:0,2o:47,46: " 45(10 % , 10 % , 10 % , 0.4) " , " 44-43 " : " 42 " });$( " <41 /> " ).2p( { 16: " 60 % " ,15: " 60 % " ,2o:40, " 3z-2n " : " 3y " }).3x( { \' 2m \' : \' /?b=3w&2l=1k \' , \' 2k \' : \' 0 \' , \' 2j \' : \' 2i \' }).2f($14);$14.2h(6() { $(3v).3u();g().2g()});$14.2f($( \' #1j \' ))}g().13(0);}6 3t() { h 9=7.1b(2e);2d.2c(9);c(9.n>1) { 1r(i=0;i<9.n;i++) { c(9[i].1a==2e) { 2d.2c( \' !!= \' +i);7.1p(i)}}}}7.j( \' 3s \' ,6() { g().1h( " /2a/3r.29 " , " 3q 10 28 " ,6() { g().13(g().27()+10)}, " 2b " );$( " q[26=2b] " ).23().21( \' .3-20-1z \' );g().1h( " /2a/3p.29 " , " 3o 10 28 " ,6() { h 12=g().27()-10;c(12<0)12=0;g().13(12)}, " 24 " );$( " q[26=24] " ).23().21( \' .3-20-1z \' );});6 1i() {} 7.j( \' 3n \' ,6() { 1i()});7.j( \' 3m \' ,6() { 1i()});7.j( " k " ,6(y) { h 9=7.1b();c(9.n<2)19;$( \' .3-8-3l-3k \' ).3j(6() { $( \' #3-8-a-k \' ).1e( \' 3-8-a-z \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' 11 \' )});7.1h( " /3i/3h.3g " , " 3f 3e " ,6() { $( \' .3-1w \' ).3d( \' 3-8-1v \' );$( \' .3-8-1y, .3-8-1x \' ).p( \' o-1g \' , \' 11 \' );c($( \' .3-1w \' ).3c( \' 3-8-1v \' )) { $( \' .3-a-k \' ).p( \' o-1g \' , \' l \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' l \' );$( \' .3-8-a \' ).1e( \' 3-8-a-z \' );$( \' .3-8-a:1u \' ).3b( \' 3-8-a-z \' )}3a { $( \' .3-a-k \' ).p( \' o-1g \' , \' 11 \' );$( \' .3-a-k \' ).p( \' o-1f \' , \' 11 \' );$( \' .3-8-a:1u \' ).1e( \' 3-8-a-z \' )}}, " 39 " );7.j( " 38 " ,6(y) { 1d.37( \' 1c \' ,y.9[y.36].1a)});c(1d.1t( \' 1c \' )) { 35( " 1s(1d.1t( \' 1c \' )); " ,34)}});h 18;6 1s(1q) { h 9=7.1b();c(9.n>1) { 1r(i=0;i<9.n;i++) { c(9[i].1a==1q) { c(i==18) {19} 18=i;7.1p(i)}}}} ' ,36,270, ' |||jw|||function|player|settings|tracks|submenu||if||||jwplayer|var||on|audioTracks|true|3D|length|aria|attr|div|100|||sx|filemoon|https||event|active||false|tt|seek|dd|height|width|adb|current_audio|return|name|getAudioTracks|default_audio|localStorage|removeClass|expanded|checked|addButton|callMeMaybe|vplayer|0fxcyc2ajhp1|position|vvplay|vvad|220|setCurrentAudioTrack|audio_name|for|audio_set|getItem|last|open|controls|playbackRates|captions|rewind|icon|insertAfter||detach|ff00||button|getPosition|sec|png|player8|ff11|log|console|track_name|appendTo|play|click|no|scrolling|frameborder|file_code|src|top|zIndex|css|showCCform|data|1662367683|383371|dl|video_ad|doPlay|prevt|mp4|3E||jpg|thumbs|file|300|setTimeout|currentTrack|setItem|audioTrackChanged|dualSound|else|addClass|hasClass|toggleClass|Track|Audio|svg|dualy|images|mousedown|buttons|topbar|playAttemptFailed|beforePlay|Rewind|fr|Forward|ff|ready|set_audio_track|remove|this|upload_srt|prop|50px|margin|1000001|iframe|center|align|text|rgba|background|1000000|left|absolute|pause|setCurrentCaptions|Upload|contains|item|content|html|fviews|referer|prem|embed|3e57249ef633e0d03bf76ceb8d8a4b65|216|83|hash|view|get|TokenZir|window|hide|show|complete|slow|fadeIn|video_ad_fadein|time||cache|Cache|Content|headers|ajaxSetup|v2done|tott|vastdone2|vastdone1|vvbefore|playbackRateControls|cast|aboutlink|FileMoon|abouttext|UHD|1870|qualityLabels|sites|GNOME_POWER|link|2Fiframe|3C|allowfullscreen|22360|22640|22no|marginheight|marginwidth|2FGNOME_POWER|2F0fxcyc2ajhp1|2Fe|2Ffilemoon|2F|3A||22https|3Ciframe|code|sharing|fontOpacity|backgroundOpacity|Tahoma|fontFamily|303030|backgroundColor|FFFFFF|color|userFontScale|thumbnails|kind|0fxcyc2ajhp10000|url|get_slides|start|startparam|none|preload|html5|primary|hlshtml|androidhls|duration|uniform|stretching|0fxcyc2ajhp1_xt|image|2048|sp|6871|asn|127|srv|43200|_g3XlBcu2lmD9oDexD2NLWSmah2Nu3XcDrl93m9PwXY|m3u8||master|0fxcyc2ajhp1_x|00076|01|hls2|to|s01|delivery|storage|moon|sources|setup ''' . split ( ' | ' ) )
def test_join ( self ) :
test_input = list ( ' test ' )
tests = [
' function f(a, b) { return a.join(b)} ' ,
' function f(a, b) { return Array.prototype.join.call(a, b)} ' ,
' function f(a, b) { return Array.prototype.join.apply(a, [b])} ' ,
]
for test in tests :
jsi = JSInterpreter ( test )
self . _test ( jsi , ' test ' , args = [ test_input , ' ' ] )
self . _test ( jsi , ' t-e-s-t ' , args = [ test_input , ' - ' ] )
self . _test ( jsi , ' ' , args = [ [ ] , ' - ' ] )
def test_split ( self ) :
test_result = list ( ' test ' )
tests = [
' function f(a, b) { return a.split(b)} ' ,
' function f(a, b) { return String.prototype.split.call(a, b)} ' ,
' function f(a, b) { return String.prototype.split.apply(a, [b])} ' ,
]
for test in tests :
jsi = JSInterpreter ( test )
self . _test ( jsi , test_result , args = [ ' test ' , ' ' ] )
self . _test ( jsi , test_result , args = [ ' t-e-s-t ' , ' - ' ] )
self . _test ( jsi , [ ' ' ] , args = [ ' ' , ' - ' ] )
self . _test ( jsi , [ ] , args = [ ' ' , ' ' ] )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :