Browse Source

Add tests

master
JustAnotherArchivist 6 years ago
parent
commit
47d2dedc53
2 changed files with 9216 additions and 0 deletions
  1. +300
    -0
      test.py
  2. +8916
    -0
      testdata.py

+ 300
- 0
test.py View File

@@ -0,0 +1,300 @@
import parse
import testdata
import unittest
import unittest.mock


class TestCase(unittest.TestCase):
'''
Base test case class
'''

def __str__(self):
'''
Overwrite the standard string representation by an easier to read version.
'''
# Based on http://stackoverflow.com/a/18460031
return '.'.join([self.__class__.__module__, self.__class__.__name__, self._testMethodName])

def shortDescription(self):
'''
Disable displaying the first line of the docstring instead of module.class.method.
'''
# http://www.saltycrane.com/blog/2012/07/how-prevent-nose-unittest-using-docstring-when-verbosity-2/
return None


class TestStrEnum(TestCase):
def test_clean_representation(self):
self.assertEqual(repr(parse.Type.group), 'Type.group')
self.assertEqual(repr(parse.Type.brackets), 'Type.brackets')
self.assertEqual(repr(parse.Modifier.negate), 'Modifier.negate')
self.assertEqual(repr(parse.Modifier.plus), 'Modifier.plus')


class TestJSTypes(TestCase):
def test_equality(self):
self.assertEqual(parse.JSBool(True), parse.JSBool(True))
self.assertEqual(parse.JSBool(False), parse.JSBool(False))
self.assertNotEqual(parse.JSBool(True), parse.JSBool(False))
self.assertNotEqual(parse.JSBool(False), parse.JSBool(True))

self.assertEqual(parse.JSInt(0), parse.JSInt(0))
self.assertEqual(parse.JSInt(42), parse.JSInt(42))
self.assertEqual(parse.JSInt(-13), parse.JSInt(-13))
self.assertNotEqual(parse.JSInt(0), parse.JSInt(42))
self.assertNotEqual(parse.JSInt(42), parse.JSInt(0))
self.assertNotEqual(parse.JSInt(0), parse.JSInt(-13))
self.assertNotEqual(parse.JSInt(-13), parse.JSInt(42))

self.assertEqual(parse.JSString(''), parse.JSString(''))
self.assertEqual(parse.JSString('test'), parse.JSString('test'))
self.assertNotEqual(parse.JSString(''), parse.JSString('test'))

# Comparisons between different types are currently not supported (JS's equality algorithm is a nightmare) and always return False
self.assertNotEqual(parse.JSBool(True), parse.JSInt(1))
self.assertNotEqual(parse.JSBool(True), parse.JSString('true'))

def test_operators(self):
self.assertEqual(parse.JSBool(True) + parse.JSBool(True), parse.JSInt(2))
self.assertEqual(parse.JSBool(True) + parse.JSInt(41), parse.JSInt(42))
self.assertEqual(parse.JSBool(True) + parse.JSString('42'), parse.JSString('true42'))
self.assertEqual(parse.JSBool(True) - parse.JSBool(True), parse.JSInt(0))
self.assertEqual(parse.JSBool(False) - parse.JSBool(True), parse.JSInt(-1))
self.assertEqual(parse.JSBool(True) - parse.JSInt(3), parse.JSInt(-2))
self.assertEqual(parse.JSBool(True) - parse.JSString('14'), parse.JSInt(-13))
self.assertEqual(parse.JSBool(True) - parse.JSString(''), parse.JSInt(1))
#self.assertEqual(parse.JSBool(True) - parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSBool(True) - parse.JSString('3test'), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSBool(True) * parse.JSBool(True), parse.JSInt(1))
self.assertEqual(parse.JSBool(False) * parse.JSBool(True), parse.JSInt(0))
self.assertEqual(parse.JSBool(True) * parse.JSInt(42), parse.JSInt(42))
self.assertEqual(parse.JSBool(False) * parse.JSInt(42), parse.JSInt(0))
self.assertEqual(parse.JSBool(True) * parse.JSString('13'), parse.JSInt(13))
self.assertEqual(parse.JSBool(True) * parse.JSString(''), parse.JSInt(0))
#self.assertEqual(parse.JSBool(True) * parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSBool(True) * parse.JSString('2test'), parse.JSInt(NaN)) # Not supported

self.assertEqual(parse.JSInt(13) + parse.JSBool(True), parse.JSInt(14))
self.assertEqual(parse.JSInt(13) + parse.JSInt(29), parse.JSInt(42))
self.assertEqual(parse.JSInt(13) + parse.JSString('29'), parse.JSString('1329'))
self.assertEqual(parse.JSInt(13) + parse.JSString(''), parse.JSString('13'))
self.assertEqual(parse.JSInt(13) + parse.JSString('test'), parse.JSString('13test'))
self.assertEqual(parse.JSInt(13) - parse.JSBool(True), parse.JSInt(12))
self.assertEqual(parse.JSInt(13) - parse.JSInt(12), parse.JSInt(1))
self.assertEqual(parse.JSInt(13) - parse.JSString('15'), parse.JSInt(-2))
self.assertEqual(parse.JSInt(13) - parse.JSString(''), parse.JSInt(13))
#self.assertEqual(parse.JSInt(13) - parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSInt(13) - parse.JSString('13test'), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSInt(3) * parse.JSBool(True), parse.JSInt(3))
self.assertEqual(parse.JSInt(3) * parse.JSInt(4), parse.JSInt(12))
self.assertEqual(parse.JSInt(3) * parse.JSString('4'), parse.JSInt(12))
self.assertEqual(parse.JSInt(3) * parse.JSString(''), parse.JSInt(0))
#self.assertEqual(parse.JSInt(3) * parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSInt(3) * parse.JSString('1test'), parse.JSInt(NaN)) # Not supported

self.assertEqual(parse.JSString('1') + parse.JSBool(True), parse.JSString('1true'))
self.assertEqual(parse.JSString('') + parse.JSBool(False), parse.JSString('false'))
self.assertEqual(parse.JSString('test') + parse.JSBool(True), parse.JSString('testtrue'))
self.assertEqual(parse.JSString('1') + parse.JSInt(1), parse.JSString('11'))
self.assertEqual(parse.JSString('1') + parse.JSString('1'), parse.JSString('11'))
self.assertEqual(parse.JSString('13') - parse.JSBool(True), parse.JSInt(12))
self.assertEqual(parse.JSString('') - parse.JSBool(True), parse.JSInt(-1))
#self.assertEqual(parse.JSString('test') - parse.JSBool(True), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('3test') - parse.JSBool(True), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSString('1') - parse.JSInt(3), parse.JSInt(-2))
self.assertEqual(parse.JSString('') - parse.JSInt(-3), parse.JSInt(3))
#self.assertEqual(parse.JSString('test') - parse.JSInt(13), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('13test') - parse.JSInt(13), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSString('13') - parse.JSString('2'), parse.JSInt(11))
self.assertEqual(parse.JSString('13') - parse.JSString(''), parse.JSInt(13))
self.assertEqual(parse.JSString('') - parse.JSString('-3'), parse.JSInt(3))
#self.assertEqual(parse.JSString('test') - parse.JSString('2'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('13test') - parse.JSString('2'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('2') - parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('2') - parse.JSString('13test'), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSString('3') * parse.JSBool(True), parse.JSInt(3))
self.assertEqual(parse.JSString('') * parse.JSBool(True), parse.JSInt(0))
#self.assertEqual(parse.JSString('test') * parse.JSBool(True), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('13test') * parse.JSBool(True), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSString('3') * parse.JSInt(2), parse.JSInt(6))
self.assertEqual(parse.JSString('') * parse.JSInt(13), parse.JSInt(0))
#self.assertEqual(parse.JSString('test') * parse.JSInt(1), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('13test') * parse.JSInt(1), parse.JSInt(NaN)) # Not supported
self.assertEqual(parse.JSString('3') * parse.JSString('2'), parse.JSInt(6))
self.assertEqual(parse.JSString('3') * parse.JSString(''), parse.JSInt(0))
self.assertEqual(parse.JSString('') * parse.JSString('3'), parse.JSInt(0))
#self.assertEqual(parse.JSString('3') * parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('') * parse.JSString('test'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('test') * parse.JSString('3'), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('test') * parse.JSString(''), parse.JSInt(NaN)) # Not supported
#self.assertEqual(parse.JSString('3test') * parse.JSString('3'), parse.JSInt(NaN)) # Not supported

def test_casting(self):
# Casting to Python objects
self.assertEqual(bool(parse.JSBool(True)), True)
self.assertEqual(bool(parse.JSBool(False)), False)
self.assertEqual(int(parse.JSBool(True)), 1)
self.assertEqual(int(parse.JSBool(False)), 0)
self.assertEqual(str(parse.JSBool(True)), 'true') # JavaScript capitalisation!
self.assertEqual(str(parse.JSBool(False)), 'false')

self.assertEqual(bool(parse.JSInt(0)), False)
self.assertEqual(bool(parse.JSInt(42)), True)
self.assertEqual(int(parse.JSInt(0)), 0)
self.assertEqual(int(parse.JSInt(42)), 42)
self.assertEqual(str(parse.JSInt(0)), '0')
self.assertEqual(str(parse.JSInt(42)), '42')

self.assertEqual(bool(parse.JSString('')), False)
self.assertEqual(bool(parse.JSString('test')), True)
self.assertEqual(int(parse.JSString('')), 0)
#self.assertEqual(int(parse.JSString('test')), NaN) # Not supported
self.assertEqual(int(parse.JSString('0')), 0)
self.assertEqual(int(parse.JSString('-13')), -13)
self.assertEqual(str(parse.JSString('')), '')
self.assertEqual(str(parse.JSString('test')), 'test')

# Casting to JS types
self.assertEqual(parse.JSBool(parse.JSBool(True)), parse.JSBool(True))
self.assertEqual(parse.JSBool(parse.JSBool(False)), parse.JSBool(False))
self.assertEqual(parse.JSInt(parse.JSBool(True)), parse.JSInt(1))
self.assertEqual(parse.JSInt(parse.JSBool(False)), parse.JSInt(0))
self.assertEqual(parse.JSString(parse.JSBool(True)), parse.JSString('true')) # JavaScript capitalisation!
self.assertEqual(parse.JSString(parse.JSBool(False)), parse.JSString('false'))

self.assertEqual(parse.JSBool(parse.JSInt(0)), parse.JSBool(False))
self.assertEqual(parse.JSBool(parse.JSInt(42)), parse.JSBool(True))
self.assertEqual(parse.JSInt(parse.JSInt(0)), parse.JSInt(0))
self.assertEqual(parse.JSInt(parse.JSInt(42)), parse.JSInt(42))
self.assertEqual(parse.JSString(parse.JSInt(0)), parse.JSString('0'))
self.assertEqual(parse.JSString(parse.JSInt(42)), parse.JSString('42'))

self.assertEqual(parse.JSBool(parse.JSString('')), parse.JSBool(False))
self.assertEqual(parse.JSBool(parse.JSString('test')), parse.JSBool(True))
#self.assertEqual(parse.JSInt(parse.JSString('')), parse.JSInt(0)) # Not supported (yet?)
#self.assertEqual(parse.JSInt(parse.JSString('test')), parse.JSInt(NaN)) # Not supported (yet?)
self.assertEqual(parse.JSInt(parse.JSString('0')), parse.JSInt(0))
self.assertEqual(parse.JSInt(parse.JSString('-13')), parse.JSInt(-13))
self.assertEqual(parse.JSString(parse.JSString('')), parse.JSString(''))
self.assertEqual(parse.JSString(parse.JSString('test')), parse.JSString('test'))

def test_repr(self):
self.assertEqual(repr(parse.JSBool(True)), 'JSBool(True)')
self.assertEqual(repr(parse.JSBool(False)), 'JSBool(False)')
self.assertEqual(repr(parse.JSInt(0)), 'JSInt(0)')
self.assertEqual(repr(parse.JSInt(-13)), 'JSInt(-13)')
self.assertEqual(repr(parse.JSInt(42)), 'JSInt(42)')
self.assertEqual(repr(parse.JSString('')), "JSString('')")
self.assertEqual(repr(parse.JSString('test')), "JSString('test')")


class TestItem(TestCase):
def test_basic(self):
item = parse.Item(parse.Type.group, [], values = [])
item = parse.Item(parse.Type.group, [parse.Modifier.plus], values = [])
with self.assertRaises(ValueError):
parse.Item(-1, [])
with self.assertRaises(TypeError):
parse.Item(parse.Type.brackets, -1)
with self.assertRaises(ValueError):
parse.Item(parse.Type.brackets, [-1])
with self.assertRaises(ValueError):
parse.Item(parse.Type.group, []) # no values

def test_evaluate_brackets(self):
def test_brackets(modifiers, result):
self.assertEqual(parse.Item(parse.Type.brackets, modifiers).evaluate(), result)

test_brackets([], parse.JSString(''))
test_brackets([parse.Modifier.plus], parse.JSInt(0))
test_brackets([parse.Modifier.negate], parse.JSBool(False))
# ++[] -> syntax error
test_brackets([parse.Modifier.plus, parse.Modifier.negate], parse.JSInt(0))
test_brackets([parse.Modifier.negate, parse.Modifier.plus], parse.JSBool(True))
test_brackets([parse.Modifier.negate, parse.Modifier.negate], parse.JSBool(True))
# +++[] -> syntax error
# ++![] -> syntax error
test_brackets([parse.Modifier.plus, parse.Modifier.negate, parse.Modifier.plus], parse.JSInt(1))
test_brackets([parse.Modifier.plus, parse.Modifier.negate, parse.Modifier.negate], parse.JSInt(1))
# !++[] -> syntax error
test_brackets([parse.Modifier.negate, parse.Modifier.plus, parse.Modifier.negate], parse.JSBool(True))
test_brackets([parse.Modifier.negate, parse.Modifier.negate, parse.Modifier.plus], parse.JSBool(False))
test_brackets([parse.Modifier.negate, parse.Modifier.negate, parse.Modifier.negate], parse.JSBool(False))

def test_evaluate_group(self):
item = parse.Item(parse.Type.group, [], values = [])
with self.assertRaises(ValueError):
item.evaluate() # No evaluateFunction specified
with self.assertRaises(ValueError):
item.evaluate(13) # Not a callable

mock = unittest.mock.Mock(return_value = 42)
item = parse.Item(parse.Type.group, [], values = [parse.Item(parse.Type.brackets, [parse.Modifier.plus])])
self.assertEqual(item.evaluate(evaluateFunction = mock), 42)
self.assertEqual(mock.call_count, 1)
self.assertEqual(len(mock.call_args), 2)
self.assertEqual(len(mock.call_args[0]), 2)
self.assertEqual(len(mock.call_args[1]), 0)
self.assertIs(mock.call_args[0][0], item.values)
self.assertIs(mock.call_args[0][1], item.modifiers)


class TestFunctions(TestCase):
def test_parse(self):
self.assertEqual(parse.parse('!![]'), [parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate])])
self.assertEqual(parse.parse('!![]+!+![]'), [
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.plus, parse.Modifier.negate]),
])
self.assertEqual(parse.parse('(!![]+!+![]+[])+(+!![]+[])'), [
parse.Item(parse.Type.group, [], [
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.plus, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
parse.Item(parse.Type.group, [], [
parse.Item(parse.Type.brackets, [parse.Modifier.plus, parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
])
self.assertEqual(parse.parse('+((!![]+!+![]+[])+(+!![]+[]))'), [
parse.Item(parse.Type.group, [parse.Modifier.plus], values = [
parse.Item(parse.Type.group, [], values = [
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.plus, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
parse.Item(parse.Type.group, [], values = [
parse.Item(parse.Type.brackets, [parse.Modifier.plus, parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
]),
])

def test_evaluate(self):
self.assertEqual(parse.evaluate([parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate])]), parse.JSBool(True))
self.assertEqual(parse.evaluate([
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
]), parse.JSInt(2))
self.assertEqual(parse.evaluate([
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]), parse.JSString('2'))
self.assertEqual(parse.evaluate([
parse.Item(parse.Type.group, [], values = [
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, [parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
parse.Item(parse.Type.group, [], values = [
parse.Item(parse.Type.brackets, [parse.Modifier.plus, parse.Modifier.negate, parse.Modifier.negate]),
parse.Item(parse.Type.brackets, []),
]),
]), parse.JSString('21'))

def test_crack(self):
for url, html, result in testdata.data:
self.assertEqual(parse.crack(url, html), parse.JSInt(result))

+ 8916
- 0
testdata.py
File diff suppressed because it is too large
View File


Loading…
Cancel
Save