[test] jstest fixes

* direct execution comment accidental removal
* zip type check in 'traverse'
* less convoluted 'variables' in JSInterpreter initialization
* tiny bit more meaningful log messages
* changing single letter flags to more explanatory names
* refactoring skip test logic
This commit is contained in:
sulyi 2016-12-27 06:28:17 +01:00
parent 3b536690d7
commit 3f075d87da
17 changed files with 68 additions and 59 deletions

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _RELATIONS from youtube_dl.jsinterp.tstream import _RELATIONS
skip = {'i': 'Interpreting if statement not yet implemented'} skip = {'interpret': 'Interpreting if statement not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
skip = {'i': 'Interpreting debugger statement not yet implemented', skip = {'interpret': 'Interpreting debugger statement not yet implemented',
'p': 'Test not yet implemented: missing code and ast'} 'parse': 'Test not yet implemented: missing code and ast'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
skip = {'i': 'Interpreting do loop not yet implemented'} skip = {'interpret': 'Interpreting do loop not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
skip = {'i': 'Interpreting for empty loop not yet implemented'} skip = {'interpret': 'Interpreting for empty loop not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS
skip = {'i': 'Interpreting for in loop not yet implemented'} skip = {'interpret': 'Interpreting for in loop not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
skip = {'i': 'Interpreting for loop not yet implemented'} skip = {'interpret': 'Interpreting for loop not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS
skip = {'i': 'Interpreting function expression not yet implemented'} skip = {'interpret': 'Interpreting function expression not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
skip = {'i': 'Interpreting label not yet implemented', skip = {'interpret': 'Interpreting label not yet implemented',
'p': 'Test not yet implemented: missing code and ast'} 'parse': 'Test not yet implemented: missing code and ast'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _OPERATORS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _OPERATORS
skip = {'i': 'Interpreting object literals not yet implemented'} skip = {'interpret': 'Interpreting object literals not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _OPERATORS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _OPERATORS
skip = {'i': 'Interpreting built-in fields not yet implemented'} skip = {'interpret': 'Interpreting built-in fields not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS
skip = {'i': 'Interpreting switch statement not yet implemented'} skip = {'interpret': 'Interpreting switch statement not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
skip = {'i': 'Interpreting try statement not yet implemented', skip = {'interpret': 'Interpreting try statement not yet implemented',
'p': 'Test not yet implemented: missing code and ast'} 'parse': 'Test not yet implemented: missing code and ast'}
tests = [ tests = [
{ {

View File

@ -1,5 +1,5 @@
skip = {'p': True} skip = {'parse': True}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS from youtube_dl.jsinterp.tstream import _ASSIGN_OPERATORS, _UNARY_OPERATORS, _RELATIONS
skip = {'i': 'Interpreting while loop not yet implemented'} skip = {'interpret': 'Interpreting while loop not yet implemented'}
tests = [ tests = [
{ {

View File

@ -1,7 +1,7 @@
from youtube_dl.jsinterp.jsgrammar import Token from youtube_dl.jsinterp.jsgrammar import Token
skip = {'i': 'Interpreting with statement not yet implemented', skip = {'interpret': 'Interpreting with statement not yet implemented',
'p': 'Test not yet implemented: missing code and ast'} 'parse': 'Test not yet implemented: missing code and ast'}
tests = [ tests = [
{ {

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
# Allow direct execution
import os import os
import sys import sys
import logging import logging
@ -28,7 +29,7 @@ class TestJSInterpreter(unittest.TestCase):
def generator(test_case, name): def generator(test_case, name):
def test_template(self): def test_template(self):
for test in test_case['subtests']: for test in test_case['subtests']:
jsi = JSInterpreter(test['code'], variables=None if 'globals' not in test else test['globals']) jsi = JSInterpreter(test['code'], variables=test.get('globals'))
if 'asserts' in test: if 'asserts' in test:
for a in test['asserts']: for a in test['asserts']:
if 'call' in a: if 'call' in a:
@ -36,34 +37,39 @@ def generator(test_case, name):
else: else:
self.assertEqual(jsi.run(), a['value']) self.assertEqual(jsi.run(), a['value'])
else: else:
log.debug('No asserts, skipping subtest') log.debug('No assertion for subtest, skipping')
log = logging.getLogger('TestJSInterpreter.%s' % name) log = logging.getLogger('TestJSInterpreter.%s' % name)
return test_template
if 'i' not in test_case['skip']:
reason = False
else:
reason = test_case['skip']['i']
return test_template if not reason else unittest.skip(reason)(test_template)
# And add them to TestJSInterpreter # And add them to TestJSInterpreter
for n, tc in enumerate(defs): for n, tc in enumerate(defs):
if 'i' not in tc['skip'] or tc['skip']['i'] is not True: reason = tc['skip'].get('interpret', False)
tname = 'test_' + str(tc['name']) tname = 'test_' + str(tc['name'])
i = 1 i = 1
while hasattr(TestJSInterpreter, tname): while hasattr(TestJSInterpreter, tname):
tname = 'test_%s_%d' % (tc['name'], i) tname = 'test_%s_%d' % (tc['name'], i)
i += 1 i += 1
if any('asserts' in test for test in tc['subtests']):
test_method = generator(tc, tname) if reason is not True:
test_method.__name__ = str(tname) log_reason = 'Entirely'
setattr(TestJSInterpreter, test_method.__name__, test_method) elif not any('asserts' in test for test in tc['subtests']):
del test_method log_reason = '''There isn't any assertion'''
else: else:
log = logging.getLogger('TestJSInterpreter') log_reason = None
log.debug('''Skipping %s:There isn't any assertion''' % tname)
if log_reason is not None:
test_method = generator(tc, tname)
test_method.__name__ = str(tname)
if reason is not False:
test_method.__unittest_skip__ = True
test_method.__unittest_skip_why__ = reason
setattr(TestJSInterpreter, test_method.__name__, test_method)
del test_method
else:
log = logging.getLogger('TestJSInterpreter')
log.debug('Skipping %s:%s' % (tname, log_reason))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
# Allow direct execution
import os import os
import sys import sys
import logging import logging
@ -18,7 +19,7 @@ from .jstests import gettestcases
def traverse(node, tree_types=(list, tuple)): def traverse(node, tree_types=(list, tuple)):
if type(node) == zip: if sys.version_info > (3,) and isinstance(node, zip):
node = list(copy.deepcopy(node)) node = list(copy.deepcopy(node))
if isinstance(node, tree_types): if isinstance(node, tree_types):
tree = [] tree = []
@ -42,35 +43,37 @@ class TestJSInterpreterParse(unittest.TestCase):
def generator(test_case, name): def generator(test_case, name):
def test_template(self): def test_template(self):
for a in test_case['subtests']: for a in test_case['subtests']:
jsi = JSInterpreter(a['code'], variables=None if 'globals' not in a else a['globals']) jsi = JSInterpreter(a['code'], variables=a.get('globals'))
parsed = list(jsi.parse()) parsed = list(jsi.parse())
if 'ast' in a: if 'ast' in a:
self.assertEqual(traverse(parsed), traverse(a['ast'])) self.assertEqual(traverse(parsed), traverse(a['ast']))
else: else:
log.debug('No AST, trying to parsing only') log.debug('No AST for subtest, trying to parse only')
log = logging.getLogger('TestJSInterpreterParse.%s' + name) log = logging.getLogger('TestJSInterpreterParse.%s' % name)
return test_template
if 'p' not in test_case['skip']:
reason = False
else:
reason = test_case['skip']['p']
return test_template if not reason else unittest.skip(reason)(test_template)
# And add them to TestJSInterpreterParse # And add them to TestJSInterpreterParse
for n, tc in enumerate(defs): for n, tc in enumerate(defs):
if 'p' not in tc['skip'] or tc['skip']['p'] is not True: reason = tc['skip'].get('parse', False)
tname = 'test_' + str(tc['name']) tname = 'test_' + str(tc['name'])
i = 1 i = 1
while hasattr(TestJSInterpreterParse, tname): while hasattr(TestJSInterpreterParse, tname):
tname = 'test_%s_%d' % (tc['name'], i) tname = 'test_%s_%d' % (tc['name'], i)
i += 1 i += 1
if reason is not True:
test_method = generator(tc, tname) test_method = generator(tc, tname)
if reason is not False:
test_method.__unittest_skip__ = True
test_method.__unittest_skip_why__ = reason
test_method.__name__ = str(tname) test_method.__name__ = str(tname)
setattr(TestJSInterpreterParse, test_method.__name__, test_method) setattr(TestJSInterpreterParse, test_method.__name__, test_method)
del test_method del test_method
else:
log = logging.getLogger('TestJSInterpreterParse')
log.debug('Skipping %s:Entirely' % tname)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()