mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2024-11-21 14:18:57 -07:00
Add the new test suite.
This test suite has been in use for a long time now, in place of the obsolete and unmanageable testparser.py and testfuncs.py. It verifies the complete optimizer output to stdout and stderr, to ensure that the output matches the expectations. See unit_tests/README.txt for more info.
This commit is contained in:
parent
7fbde0269c
commit
1867dc78e7
547 changed files with 11680 additions and 0 deletions
778
run-tests.py
Executable file
778
run-tests.py
Executable file
|
@ -0,0 +1,778 @@
|
|||
#!/usr/bin/env python2
|
||||
#
|
||||
# (C) Copyright 2015-2019 Sei Lisa. All rights reserved.
|
||||
#
|
||||
# This file is part of LSL PyOptimizer.
|
||||
#
|
||||
# LSL PyOptimizer is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# LSL PyOptimizer is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with LSL PyOptimizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Unit testing program.
|
||||
# Checks all files in unit_tests/*.suite/ with extensions .lsl or .run.
|
||||
# When one is found, it's considered a test (if both exist, they are considered
|
||||
# a single test).
|
||||
#
|
||||
# Extension .lsl is for source files to test. If the first line starts with
|
||||
# "// " then the rest of the line is taken as the docstring of that test
|
||||
# (visible with Eric or with option -v). The script is also fed as standard
|
||||
# input to the program.
|
||||
# .run defines the command-line parameters for invocation. A test can be run
|
||||
# without a .lsl file but with a .run file. If not present, the .lsl file
|
||||
# is run with the command line 'main.py -'. The quoting rules are sh-style.
|
||||
# The executable name is ignored, but needs to be present.
|
||||
# .out is for expected output to stdout. If the first line is "REGEX", then
|
||||
# the rest of the file is interpreted as a regular expression that the
|
||||
# output is matched against. Otherwise the output must exactly match.
|
||||
# If the file is not present, that's equivalent to an empty file, i.e. no
|
||||
# output is expected.
|
||||
# .err is like .out but for expected output to stderr, with the same features.
|
||||
# .skp is for a file that if present, will skip this test. The contents are
|
||||
# displayed as the reason for being skipped.
|
||||
# .fail is for a file that, when present, marks the test as expected to fail.
|
||||
# Its contents are not read (an empty file is OK).
|
||||
#
|
||||
# A test passes when the stdout output matches the .out file, and the stderr
|
||||
# output matches the .err file. Both default to empty strings.
|
||||
#
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
#import math
|
||||
import main
|
||||
import glob
|
||||
import re
|
||||
try:
|
||||
import difflib
|
||||
except ImportError:
|
||||
difflib = None
|
||||
import StringIO as StringStream
|
||||
from lslopt import lslcommon,lslfuncs,lslparse,lsloutput,lslloadlib
|
||||
from lslopt.lslcommon import nr
|
||||
|
||||
class EArgError(Exception):
|
||||
pass
|
||||
|
||||
def parseArgs(s):
|
||||
"""Parse a command line, Bourne shell-style"""
|
||||
if s is None:
|
||||
return None
|
||||
|
||||
args = []
|
||||
|
||||
# States
|
||||
Space = 0
|
||||
SBackslash = 1
|
||||
Normal = 2
|
||||
NBackslash = 3
|
||||
DQuote = 4
|
||||
DQBackslash = 5
|
||||
SQuote = 6
|
||||
|
||||
State = Space
|
||||
p = 0
|
||||
Len = len(s)
|
||||
arg = ''
|
||||
|
||||
while p < Len:
|
||||
c = s[p]
|
||||
p += 1
|
||||
if State in (Space, Normal):
|
||||
if c == '\\':
|
||||
State = NBackslash if State == Normal else SBackslash
|
||||
elif c == '"':
|
||||
State = DQuote
|
||||
elif c == "'":
|
||||
State = SQuote
|
||||
elif c in (' ', '\t'):
|
||||
if State == Normal:
|
||||
State = Space
|
||||
args.append(arg)
|
||||
arg = ''
|
||||
# else remain in state Space
|
||||
elif c == '\n':
|
||||
break
|
||||
else:
|
||||
State = Normal
|
||||
arg += c
|
||||
elif State in (SBackslash, NBackslash, DQBackslash):
|
||||
if c == '\n':
|
||||
State = (DQuote if State == DQBackslash
|
||||
else Space if State == SBackslash
|
||||
else Normal)
|
||||
else:
|
||||
if State == DQBackslash and c not in ('"', '`', '$', '\\'):
|
||||
arg += '\\'
|
||||
arg += c
|
||||
State = DQuote if State == DQBackslash else Normal
|
||||
elif State == DQuote:
|
||||
if c == '\\':
|
||||
State = DQBackslash
|
||||
# ` and $ are not interpreted by this parser.
|
||||
elif c == '"':
|
||||
State = Normal
|
||||
else:
|
||||
arg += c
|
||||
elif State == SQuote:
|
||||
if c == "'":
|
||||
State = Normal
|
||||
else:
|
||||
arg += c
|
||||
|
||||
if State in (SQuote, DQuote):
|
||||
raise EArgError(u"Unterminated string in .run file")
|
||||
if State in (SBackslash, NBackslash, DQBackslash):
|
||||
raise EArgError(u"Backslash before EOF in .run file")
|
||||
|
||||
if State == Normal:
|
||||
args.append(arg)
|
||||
return args
|
||||
|
||||
|
||||
#import codecs
|
||||
## sh-style argument parsing
|
||||
## identify line continuations
|
||||
#cont_re = re.compile( '\\\\\n'
|
||||
# '|(?:\.|[^ \t\n\'])'
|
||||
# r"|'[^']*'")
|
||||
## separates words
|
||||
#args_re = re.compile(r'(?:'
|
||||
# r'\\.'
|
||||
# '|[^ \t\n\'"]'
|
||||
# r'|"(?:\\.|[^"])*"'
|
||||
# r"|'[^']*'"
|
||||
# r')+')
|
||||
## matches types of parts of a word ('...', "...", \x, x)
|
||||
#part_re = re.compile(r'(?:'
|
||||
# r'\\.'
|
||||
# '|[^ \t\'"]'
|
||||
# r')+'
|
||||
# r'|"(?:\\.|[^"])*"'
|
||||
# r"|'[^']*'")
|
||||
#
|
||||
# args = args_re.findall(s)
|
||||
# for i in range(len(args)):
|
||||
# arg = args[i]
|
||||
# argout = ''
|
||||
# for match in part_re.finditer(arg):
|
||||
# part = match.group()
|
||||
# if part[0] == '"':
|
||||
# argout += codecs.escape_decode(part[1:-1])[0]
|
||||
# elif part[0] == "'":
|
||||
# argout += part[1:-1]
|
||||
# else:
|
||||
# argout += codecs.escape_decode(part)[0]
|
||||
# args[i] = argout
|
||||
# return args
|
||||
|
||||
def tryRead(fn):
|
||||
result = None
|
||||
try:
|
||||
f = open(fn, 'r')
|
||||
try:
|
||||
result = f.read()
|
||||
finally:
|
||||
f.close()
|
||||
except IOError as e:
|
||||
if e.errno != 2:
|
||||
raise
|
||||
return result
|
||||
|
||||
# In StringIO, mixing unicode and str causes problems with non-ASCII chars.
|
||||
# Avoid it by overriding the write method, to always encode unicode as UTF-8.
|
||||
class StrUTF8IO(StringStream.StringIO):
|
||||
def write(self, s):
|
||||
if type(s) == unicode:
|
||||
StringStream.StringIO.write(self, s.encode('utf8'))
|
||||
else:
|
||||
StringStream.StringIO.write(self, s)
|
||||
|
||||
def invokeMain(argv, stdin = None):
|
||||
"""Invoke main.main, substituting stdin, stdout, stderr.
|
||||
Returns tuple with stdout and stderr."""
|
||||
# Revert globals to initial state
|
||||
lslcommon.LSO = False
|
||||
lslcommon.IsCalc = False
|
||||
lslcommon.Bugs.clear()
|
||||
lslcommon.Bugs.add(6495)
|
||||
save_stdin = sys.stdin
|
||||
save_stdout = sys.stdout
|
||||
save_stderr = sys.stderr
|
||||
stdout_output = None
|
||||
stderr_output = None
|
||||
try:
|
||||
sys.stdin = StringStream.StringIO(stdin)
|
||||
sys.stdout = StrUTF8IO()
|
||||
sys.stderr = StrUTF8IO()
|
||||
sys.stdin.encoding = 'utf8'
|
||||
sys.stdout.encoding = 'utf8'
|
||||
sys.stderr.encoding = 'utf8'
|
||||
|
||||
main.main(argv)
|
||||
|
||||
stdout_output = sys.stdout.getvalue()
|
||||
stderr_output = sys.stderr.getvalue()
|
||||
finally:
|
||||
sys.stdin = save_stdin
|
||||
sys.stdout = save_stdout
|
||||
sys.stderr = save_stderr
|
||||
lslcommon.LSO = False
|
||||
lslcommon.IsCalc = False
|
||||
lslcommon.Bugs.clear()
|
||||
lslcommon.Bugs.add(6495)
|
||||
|
||||
return (stdout_output, stderr_output)
|
||||
|
||||
#def tolEqual(actual, expected, tol):
|
||||
# """Strict equality. Like reallyEqual, but a tolerance can
|
||||
# be specified for comparing floats.
|
||||
# """
|
||||
# if type(actual) != type(expected):
|
||||
# return False
|
||||
#
|
||||
# # Deal with floats (edge cases, tolerance)
|
||||
# if isinstance(actual, float):
|
||||
# # Signs must be equal
|
||||
# if math.copysign(1, actual) != math.copysign(1, expected):
|
||||
# return False
|
||||
# if math.isnan(actual):
|
||||
# # This compares the sign of NaN as well
|
||||
# return math.isnan(expected)
|
||||
# if math.isinf(actual) and math.isinf(expected):
|
||||
# return actual == expected
|
||||
# return abs(actual - expected) <= tol
|
||||
#
|
||||
# # Deal with tuples and lists (item-by-item, recursively)
|
||||
# if isinstance(actual, (tuple, list)):
|
||||
# return all(tolEqual(i1, i2, tol)
|
||||
# for i1, i2 in zip(actual, expected))
|
||||
#
|
||||
# # Fall back to 'classic' equality
|
||||
# return actual == expected
|
||||
#
|
||||
#def reallyEqual(actual, expected):
|
||||
# """Strictest equality. The types must be equal. For floats, it checks
|
||||
# that the signs are equal, even for -0.0 and for NaNs. For the rest,
|
||||
# it falls back to ==.
|
||||
# """
|
||||
# return tolEqual(actual, expected, 0.0)
|
||||
#
|
||||
#def reprEqual(self, actual, expected):
|
||||
# """Returns whether the values are equal when comparing their repr's."""
|
||||
# return repr(actual) == repr(expected)
|
||||
|
||||
class UnitTestCase(unittest.TestCase):
|
||||
pass
|
||||
|
||||
class UnitTestRegression(UnitTestCase):
|
||||
def test_regression_misc(self):
|
||||
"""Miscellaneous tests that can't be computed or are too difficult
|
||||
to compute with scripts
|
||||
"""
|
||||
sys.stderr.write('\nRunning miscellaneous tests: ')
|
||||
# Test behaviour under BUG-3763
|
||||
lslcommon.Bugs.add(3763)
|
||||
self.assertEqual(lslfuncs.llXorBase64(u"ABCDABCDABCD", u"ABCD"),
|
||||
u"AAAAAAAAABCT")
|
||||
self.assertEqual(lslfuncs.llXorBase64(u"ABCDABCDABCDABCDABCDABCDABCD",
|
||||
u"ABCD"),
|
||||
u"AAAAAAAAABCTgxCDEJODAAAAABCT")
|
||||
self.assertEqual(lslfuncs.llXorBase64(u"ABCDABCDABCD", u"ABC="),
|
||||
u"AACDEBCDEBCD")
|
||||
self.assertEqual(lslfuncs.llXorBase64(u"AQCDAQCD", u"AQC="),
|
||||
u"AACCAQCC")
|
||||
lslcommon.Bugs.discard(3763)
|
||||
|
||||
# Check that zstr returns the same type it is passed.
|
||||
self.assertEqual(type(lslfuncs.zstr(lslcommon.Key(u'x\0x'))),
|
||||
lslcommon.Key)
|
||||
|
||||
def test_regression_ll_json(self):
|
||||
from unit_tests import json
|
||||
# Patch llJsonSetValue, to allow running the test.
|
||||
json.llJsonSetValue = lambda x, y, z: u"***"
|
||||
sys.stderr.write('\nRunning JSON test module: ')
|
||||
save_stdout = sys.stdout
|
||||
save_stderr = sys.stderr
|
||||
stdout_output = False
|
||||
stderr_output = False
|
||||
try:
|
||||
sys.stdout = StringStream.StringIO()
|
||||
sys.stderr = StringStream.StringIO()
|
||||
errs = json.run_tests()
|
||||
stdout_output = sys.stdout.getvalue()
|
||||
stderr_output = sys.stderr.getvalue()
|
||||
finally:
|
||||
sys.stdout = save_stdout
|
||||
sys.stderr = save_stderr
|
||||
self.assertLessEqual(errs, 138)
|
||||
self.assertEqual(stdout_output, tryRead('unit_tests/json.out'))
|
||||
self.assertEqual(stderr_output, tryRead('unit_tests/json.err'))
|
||||
assert 'unit_tests.json' in sys.modules
|
||||
del sys.modules['unit_tests.json']
|
||||
|
||||
def test_regression_parser(self):
|
||||
"""Test the error cases. There are too many to make a test of each."""
|
||||
sys.stderr.write('\nRunning parser error tests: ')
|
||||
parser = lslparse.parser(lslloadlib.LoadLibrary())
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'f(){integer i;i>>=i;}')
|
||||
self.assertRaises(lslparse.EParseCantChangeState, parser.parse,
|
||||
'f(){if(1)state default;else;}default{timer(){}}')
|
||||
self.assertRaises(lslparse.EParseCantChangeState, parser.parse,
|
||||
'f(){if(1);else state default;}default{timer(){}}')
|
||||
self.assertRaises(lslparse.EParseCantChangeState, parser.parse,
|
||||
'f(){if(1)if(1)state default;else;else;}default{timer(){}}')
|
||||
|
||||
# Test behaviour of void functions
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){<llDie(),0,0>;}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){[<llDie(),0,0>];}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){key a=llDie();}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){key a;a=llDie();}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){do;while(llDie());}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){for(;llDie(););}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){while(llDie());}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){if(llDie());}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){if(llDie());else;}}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'default{timer(){[llDie()];}}', ('optimize',))
|
||||
parser.parse('default{timer(){[llDie()];}}')
|
||||
parser.parse('default{timer(){llDie();}}')
|
||||
parser.parse('default{timer(){(llDie());}}')
|
||||
parser.parse('default{timer(){for(llDie();1;llDie());}}'
|
||||
, ('optimize',))
|
||||
|
||||
class UnitTestCoverage(UnitTestCase):
|
||||
def test_coverage_misc(self):
|
||||
"""Miscellaneous tests that can't be computed or are too difficult
|
||||
to compute with scripts
|
||||
"""
|
||||
sys.stderr.write('\nRunning misc coverage tests: ')
|
||||
# Doesn't accept bytes
|
||||
self.assertRaises(lslfuncs.ELSLInvalidType, lslfuncs.zstr, b"blah")
|
||||
# Can't typecast float to vector
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
lslfuncs.F32(1.2), lslcommon.Vector)
|
||||
# Can't typecast integer to vector
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
1, lslcommon.Vector)
|
||||
# Can't typecast vector to key
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
lslcommon.Vector((1.,2.,3.)), lslcommon.Key)
|
||||
# Can't typecast quaternion to key
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
lslcommon.Quaternion((1.,2.,3.,4.)), lslcommon.Key)
|
||||
# Can't typecast list to vector
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
[1, 1., lslcommon.Key(u'blah'),
|
||||
lslcommon.Quaternion((1.,0.,0.,0.))],
|
||||
lslcommon.Vector)
|
||||
# Can't typecast key to integer
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.typecast,
|
||||
lslcommon.Key(u"1"), int)
|
||||
# Can't negate string
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.neg, u"3")
|
||||
# Can't add two keys
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.add,
|
||||
lslcommon.Key(u"1"), lslcommon.Key(u"2"))
|
||||
# Can't subtract two strings
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.sub,
|
||||
u"1", u"2")
|
||||
# Can't multiply two strings
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.mul,
|
||||
u"1", u"2")
|
||||
# Can't multiply quaternion and float in any order
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.mul,
|
||||
lslcommon.Quaternion((1.,2.,3.,4.)), 1.)
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.mul,
|
||||
1., lslcommon.Quaternion((1.,2.,3.,4.)))
|
||||
# Can't multiply quaternion by vector (but the opposite order is OK)
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.mul,
|
||||
lslcommon.Quaternion((1.,2.,3.,4.)),
|
||||
lslcommon.Vector((1.,2.,3.)))
|
||||
# Can't divide quaternion by vector either
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.div,
|
||||
lslcommon.Quaternion((1.,2.,3.,4.)),
|
||||
lslcommon.Vector((1.,2.,3.)))
|
||||
# Can't mod floats
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.mod, 3., 3)
|
||||
# Can't compare string and integer
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.compare, u'3', 4)
|
||||
self.assertRaises(lslfuncs.ELSLTypeMismatch, lslfuncs.less, u'3', 4)
|
||||
|
||||
# Bytes is not a valid type to multiply by (in any order)
|
||||
self.assertRaises(lslfuncs.ELSLInvalidType, lslfuncs.mul, b"a", 3)
|
||||
self.assertRaises(lslfuncs.ELSLInvalidType, lslfuncs.mul,
|
||||
lslcommon.Vector((3.,4.,5.)), b"a")
|
||||
self.assertRaises(lslfuncs.ELSLInvalidType, lslfuncs.typecast,
|
||||
b"", unicode)
|
||||
|
||||
# v2f/q2f coverage (force conversion from ints to floats)
|
||||
self.assertEqual(repr(lslfuncs.v2f(lslcommon.Vector((1,0,0)))),
|
||||
'Vector((1.0, 0.0, 0.0))')
|
||||
self.assertEqual(repr(lslfuncs.q2f(lslcommon.Quaternion((1,0,0,0)))),
|
||||
'Quaternion((1.0, 0.0, 0.0, 0.0))')
|
||||
# Key repr coverage
|
||||
self.assertEqual(repr(lslcommon.Key(u'')), "Key(u'')")
|
||||
|
||||
# string + key coverage
|
||||
self.assertEqual(lslfuncs.add(u'a', lslcommon.Key(u'b')), u'ab')
|
||||
self.assertEqual(type(lslfuncs.add(u'a', lslcommon.Key(u'b'))), unicode)
|
||||
|
||||
# The SEF table prevents this assertion from being reachable via script.
|
||||
self.assertRaises(lslfuncs.ELSLCantCompute, lslfuncs.llXorBase64Strings,
|
||||
u"AABA", u"AABA")
|
||||
self.assertRaises(lslfuncs.ELSLCantCompute, lslfuncs.llModPow,
|
||||
3, 5, 7)
|
||||
# Check invalid type in llGetListEntryType
|
||||
self.assertRaises(lslfuncs.ELSLInvalidType, lslfuncs.llGetListEntryType,
|
||||
[b'a'], 0)
|
||||
|
||||
# Check that Value2LSL raises an exception if the type is unknown.
|
||||
outmod = lsloutput.outscript()
|
||||
# Script with a single node of type Expression, containing a constant
|
||||
# of type Bytes. That's rejected by the output module.
|
||||
msg = None
|
||||
script = [nr(nt='EXPR', t='string', ch=[
|
||||
nr(nt='CONST', t='string', value=b'ab')
|
||||
])]
|
||||
save_IsCalc = lslcommon.IsCalc
|
||||
lslcommon.IsCalc = True
|
||||
try:
|
||||
try:
|
||||
outmod.output((script, ()))
|
||||
except AssertionError as e:
|
||||
msg = str(e)
|
||||
finally:
|
||||
lslcommon.IsCalc = save_IsCalc
|
||||
self.assertEqual(msg, u"Value of unknown type in Value2LSL: 'ab'")
|
||||
del msg
|
||||
# Extended assignment in output
|
||||
script = [nr(nt='EXPR', t='integer', ch=[
|
||||
nr(nt='^=', t='integer', ch=[
|
||||
nr(nt='IDENT', t='integer', name='a', scope=0),
|
||||
nr(nt='CONST', t='integer', value=3)
|
||||
])])]
|
||||
save_IsCalc = lslcommon.IsCalc
|
||||
lslcommon.IsCalc = True
|
||||
try:
|
||||
out = outmod.output((script, [{'a':{'Kind':'v','Loc':1,'Scope':0,
|
||||
'Type':'integer'}
|
||||
}]
|
||||
))
|
||||
finally:
|
||||
lslcommon.IsCalc = save_IsCalc
|
||||
|
||||
self.assertEqual(out, 'a = a ^ (3)')
|
||||
del out, script, outmod, save_IsCalc
|
||||
|
||||
def test_coverage_parser(self):
|
||||
"""Cover the error cases. There are too many to make a test of each."""
|
||||
parser = lslparse.parser(lslloadlib.LoadLibrary(
|
||||
builtins = 'unit_tests/builtins-coverage-2.txt',
|
||||
fndata = 'unit_tests/builtins-coverage-2.txt'))
|
||||
self.assertRaises(lslparse.EParseNoConversion, parser.parse,
|
||||
'f(){list L;(integer)L[0];}', ('lazylists',))
|
||||
parser = lslparse.parser(lslloadlib.LoadLibrary())
|
||||
sys.stderr.write('\nRunning parser exception coverage tests: ')
|
||||
# Parse_unary_postfix_expression
|
||||
self.assertRaises(lslparse.EParseUEOF, parser.parse, u'f(){key x=')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'f(){g();}')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'integer g;f(){g();}')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'f(){f=0;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){integer V; V[1] = 0;}', ('lazylists',))
|
||||
self.assertRaises(lslparse.EParseFunctionMismatch, parser.parse,
|
||||
'f(){list V; V[1,1] = 0;}', ('lazylists',))
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){list V; V[""] = 0;}', ('lazylists',))
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){list V; V[1] = llDie();}', ('lazylists',))
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s++;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;++s;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s=llDie();}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s+=(key)"";}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s-=s;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s*=2;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){vector v;v%=1.0;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){string s;s>>=s;}', ('extendedassignment',))
|
||||
# Parse_unary_expression
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){-"";}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){!"";}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){~"";}')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'f(){++f;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){(key)1;}')
|
||||
self.assertRaises(lslparse.EParseFunctionMismatch, parser.parse,
|
||||
'f(){list L;(integer)L[""];}', ('lazylists',))
|
||||
# Parse_factor
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""*2;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){<1,1,1>%2;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){<1,1,1>/<1,1,1>;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){<1,1,1>/"";}')
|
||||
# Parse_term
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){llDie()+1;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""-1;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){[]+llDie();}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){(key)""+(key)"";}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""+(key)"";}')
|
||||
# Parse_shift
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){"">>1;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){1<<"";}')
|
||||
# Parse_inequality
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""<"";}')
|
||||
# Parse_comparison
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){llDie()==3;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""==3;}')
|
||||
# Parse_bitbool_factor
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""&3;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){3&"";}')
|
||||
# Parse_bitxor_term
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""^3;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){3^"";}')
|
||||
# Parse_bitbool_term
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""|3;}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){3|"";}')
|
||||
# Parse_expression
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){3||"";}')
|
||||
self.assertRaises(lslparse.EParseTypeMismatch, parser.parse,
|
||||
'f(){""&&3;}')
|
||||
# Parse_optional_expression_list
|
||||
self.assertRaises(lslparse.EParseFunctionMismatch, parser.parse,
|
||||
'f(){llSay(0);}')
|
||||
self.assertRaises(lslparse.EParseAlreadyDefined, parser.parse,
|
||||
'f(){@x;@x;}')
|
||||
self.assertRaises(lslparse.EParseAlreadyDefined, parser.parse,
|
||||
'f(){integer x;integer x;}')
|
||||
self.assertRaises(lslparse.EParseAlreadyDefined, parser.parse,
|
||||
'f(integer x, integer x){}')
|
||||
self.assertRaises(lslparse.EParseAlreadyDefined, parser.parse,
|
||||
'default{timer(){}timer(){}}')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(){state state;}}')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'default{timer(){state undefined;}}')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(){switch(1){case 1;}}}', ('enableswitch',))
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(){switch(1){default;}}}', ('enableswitch',))
|
||||
self.assertRaises(lslparse.EParseInvalidBrkContArg, parser.parse,
|
||||
'default{timer(){while(1){break 0;}}}', ('breakcont',))
|
||||
self.assertRaises(lslparse.EParseInvalidBrkContArg, parser.parse,
|
||||
'default{timer(){while(1){break 2;}}}', ('breakcont',))
|
||||
self.assertRaises(lslparse.EParseInvalidBrkContArg, parser.parse,
|
||||
'default{timer(){while(1){continue 0;}}}', ('breakcont',))
|
||||
self.assertRaises(lslparse.EParseInvalidBrkContArg, parser.parse,
|
||||
'default{timer(){while(1){continue 2;}}}', ('breakcont',))
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'integer T=-TRUE;default{timer(){}}')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'list L=[[]];default{timer(){}}')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(integer i){}}')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'i = 0;',)
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(){}}state{timer(){}}')
|
||||
self.assertRaises(lslparse.EParseUndefined, parser.parse,
|
||||
'default{timer(){jump undefined;}}')
|
||||
# BuildTempGlobalsTable coverage
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
';')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'f(;')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'f();')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'integer f=')
|
||||
self.assertRaises(lslparse.EParseUEOF, parser.parse,
|
||||
'integer /*')
|
||||
self.assertRaises(lslparse.EParseSyntax, parser.parse,
|
||||
'default{timer(){}}state e;')
|
||||
|
||||
class UnitTestExpr(UnitTestCase):
|
||||
pass
|
||||
|
||||
class UnitTestLSO(UnitTestCase):
|
||||
pass
|
||||
|
||||
class UnitTestPreproc(UnitTestCase):
|
||||
pass
|
||||
|
||||
def generateScriptTests():
|
||||
"""Find all files in unit_tests/*.d/*.{lsl,run} and generate tests for
|
||||
them.
|
||||
"""
|
||||
|
||||
path = os.path.dirname(__file__)
|
||||
if path:
|
||||
os.chdir(path)
|
||||
|
||||
testsuites = ('Regression', 'Coverage', 'Expr', 'LSO', 'Preproc')
|
||||
for testsuite in testsuites:
|
||||
files = glob.glob(os.path.join('unit_tests',
|
||||
testsuite.lower() + '.suite', '*.lsl')
|
||||
) + glob.glob(os.path.join('unit_tests',
|
||||
testsuite.lower() + '.suite', '*.run')
|
||||
)
|
||||
files = list(set([os.path.splitext(x)[0] for x in files]))
|
||||
files.sort()
|
||||
for fbase in files:
|
||||
# Create a closure with the test data
|
||||
def makeTestFunction(fbase, suite):
|
||||
def TestFunction(self):
|
||||
stdin = tryRead(fbase + '.lsl') or ''
|
||||
expected_stdout = tryRead(fbase + '.out') or ''
|
||||
expected_stderr = tryRead(fbase + '.err') or ''
|
||||
runargs = (parseArgs(tryRead(fbase + '.run'))
|
||||
or (['main.py', '-y', '-'] if suite != 'Expr'
|
||||
else ['main.py',
|
||||
# Defaults for Expr:
|
||||
'-O', 'clear,optimize,constfold'
|
||||
',addstrings,expr',
|
||||
'-y',
|
||||
'-']))
|
||||
sys.stderr.write("\nRunning test %s: " % fbase)
|
||||
actual_stdout, actual_stderr = invokeMain(runargs, stdin)
|
||||
actual_stdout = (actual_stdout.replace('\r','\r\n')
|
||||
.replace('\r\n\n','\n')
|
||||
.replace('\r\n','\n'))
|
||||
|
||||
actual_stderr = (actual_stderr.replace('\r','\r\n')
|
||||
.replace('\r\n\n','\n')
|
||||
.replace('\r\n','\n'))
|
||||
|
||||
try:
|
||||
if expected_stderr.startswith('REGEX\n'):
|
||||
self.assertIsNotNone(
|
||||
re.search(expected_stderr[6:],
|
||||
actual_stderr.decode('utf8')
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.assertEqual(expected_stderr, actual_stderr)
|
||||
except AssertionError:
|
||||
sys.stderr.write('Failed'
|
||||
'\n************ expected stderr:\n')
|
||||
sys.stderr.write(expected_stderr)
|
||||
sys.stderr.write('\n************ actual stderr:\n')
|
||||
sys.stderr.write(actual_stderr)
|
||||
if difflib and expected_stderr and actual_stderr:
|
||||
sys.stderr.write('\n************ diff:\n'
|
||||
+ '\n'.join(difflib.unified_diff(
|
||||
expected_stderr.split('\n'),
|
||||
actual_stderr.split('\n'),
|
||||
'expected', 'actual', lineterm=''
|
||||
)))
|
||||
sys.stderr.write('\n************ ')
|
||||
raise
|
||||
try:
|
||||
if expected_stdout.startswith('REGEX\n'):
|
||||
self.assertIsNotNone(re.search(expected_stdout[6:],
|
||||
actual_stdout))
|
||||
else:
|
||||
self.assertEqual(expected_stdout, actual_stdout)
|
||||
except AssertionError:
|
||||
sys.stderr.write('Failed'
|
||||
'\n************ expected stdout:\n')
|
||||
sys.stderr.write(expected_stdout)
|
||||
sys.stderr.write('\n************ actual stdout:\n')
|
||||
sys.stderr.write(actual_stdout)
|
||||
if difflib and expected_stdout and actual_stdout:
|
||||
sys.stderr.write('\n************ diff:\n'
|
||||
+ '\n'.join(difflib.unified_diff(
|
||||
expected_stdout.split('\n'),
|
||||
actual_stdout.split('\n'),
|
||||
'expected', 'actual', lineterm=''
|
||||
)))
|
||||
sys.stderr.write('\n************ ')
|
||||
raise
|
||||
return TestFunction
|
||||
TestFunction = makeTestFunction(fbase, testsuite)
|
||||
# __doc__ is used by Eric
|
||||
line = ''
|
||||
try:
|
||||
f = open(fbase + '.lsl')
|
||||
try:
|
||||
line = f.readline()
|
||||
if line.endswith('\r\n'):
|
||||
line = line[:-2]
|
||||
elif line[-1:] in ('\r', '\n'):
|
||||
line = line[:-1]
|
||||
finally:
|
||||
f.close()
|
||||
except IOError as e:
|
||||
if e.errno != 2:
|
||||
raise
|
||||
TestFunction.__doc__ = line[3:] if line.startswith('// ') else None
|
||||
|
||||
TestFunction.__name__ = ('test_' + testsuite + '__'
|
||||
+ os.path.basename(fbase).replace('-','_'))
|
||||
if os.path.exists(fbase + '.fail'):
|
||||
TestFunction = unittest.expectedFailure(TestFunction)
|
||||
else:
|
||||
skip = tryRead(fbase + '.skp')
|
||||
if skip is not None:
|
||||
TestFunction = unittest.skip(skip)(TestFunction)
|
||||
setattr(globals()['UnitTest' + testsuite],
|
||||
TestFunction.__name__, TestFunction)
|
||||
|
||||
|
||||
generateScriptTests()
|
||||
if __name__ == '__main__':
|
||||
unittest.main(argv = sys.argv)
|
34
unit_tests/README.txt
Normal file
34
unit_tests/README.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
Unit testing suites. These tests are run via run-tests.py.
|
||||
|
||||
The testing is performed using the standard Python module 'unittest'. This module accepts some command-line options; we don't add any ourselves. Use 'python run-tests.py -h' for help, or look here for details: https://docs.python.org/2/library/unittest.html#command-line-interface
|
||||
|
||||
There are 5 directories defined in the code that contain tests, all of which end in .suite: regression.suite, expr.suite, lso.suite, coverage.suite, preproc.suite.
|
||||
|
||||
The files that all 5 contain are the tests themselves. The run-tests.py program reads all .run and .lsl files in each directory and takes them as tests to run.
|
||||
|
||||
A test is a series of files all with the same name and with different extensions. Running the test means running the optimizer with the parameters in the .run file (if present), giving it the .lsl file (if present) as input. The output to stdout is compared to the .out file and the output to stderr is compared to the .err file. The test passes if both match and no exception is raised; otherwise it fails.
|
||||
|
||||
These are the extensions that the test suite recognizes in more detail:
|
||||
|
||||
.lsl: Source file to test. If the first line starts with '// ', then the text in the rest of the line will be set as the docstring for the corresponding test function (visible when requesting verbose coverage).
|
||||
.run: Command line parameters for the test. Default is: 'main.py -', except in expr.suite which defaults to 'main.py -O clear,optimize,constfold,addstrings,expr -'. The syntax for the parameters is that of the Bourne shell, but '$' expansion is not supported. The 'main.py' part is the value that argv[0] will receive, but is unused otherwise.
|
||||
.out: Expected stdout resulting from the test. If the first line is REGEX then the rest of the file will be taken as a regular expression to match against, as opposed to matching the whole file contents.
|
||||
.err: Expected stderr resulting from the test. It also allows regular expression.
|
||||
.skp: If present, the test will be skipped (not run). The contents of this file are taken as the reason for the expected failure.
|
||||
.fail: If present, the test will be run, and counted as an expected failure. If a .fail file is present and the test passes, that will be counted as an unexpected success, and the program will not report success at the end. The contents will be ignored; zero-length files are OK.
|
||||
|
||||
A test is considered such when either the .lsl or the .run file are present. The default stdin for the program is the .lsl file.
|
||||
|
||||
As for the meaning of each subdirectory:
|
||||
|
||||
- regression.suite contains normal regression tests.
|
||||
- expr.suite contains regression tests that apply to expressions.
|
||||
- lso.suite contains LSO mode tests. Note that LSO support is incomplete.
|
||||
- coverage.suite contains tests that force certain code paths to execute, in order to maximize the exercised code coverage, even if some tests are trivial and unlikely to cause a regression.
|
||||
- preproc.suite is for preprocessor-related tests.
|
||||
|
||||
As for the files in this directory:
|
||||
|
||||
- cat.py just copies standard input to standard output. Used as a preprocessor for some preprocessor tests.
|
||||
- false.py just terminates with exit code 1.
|
||||
- output-list.lsl is a utility script that dumps an arbitrary list to local chat, in a format very similar to the one that the expression suite outputs (it may require manual removal of timestamps). Float precision may differ.
|
2
unit_tests/builtins-coverage-1.txt
Normal file
2
unit_tests/builtins-coverage-1.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
event ev()
|
||||
const list LIST_CONSTANT = []
|
0
unit_tests/builtins-coverage-2.txt
Normal file
0
unit_tests/builtins-coverage-2.txt
Normal file
21
unit_tests/builtins-coverage-4.txt
Normal file
21
unit_tests/builtins-coverage-4.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
const key a="\t"
|
||||
event ev(integer i)
|
||||
event ev(integer i)
|
||||
quaternion x(integer i)
|
||||
void x(integer i)
|
||||
blah x1(integer i)
|
||||
integer x2(unknown i)
|
||||
blah
|
||||
const vector a = <4,5,3,2>
|
||||
const vector a = <4,5,3,2
|
||||
const vector a = <x,4,3>
|
||||
const vector a = <4,x,3>
|
||||
const vector a = <3,4,x>
|
||||
const rotation a = <3,4,4,x>
|
||||
const list l = []
|
||||
const quaternion q=<1,2,3,4>
|
||||
const string v="
|
||||
const string q="\t"
|
||||
const unknown x3 = 3
|
||||
const list L = [1]
|
||||
const list L2 = [
|
5
unit_tests/builtins-coverage-5.txt
Normal file
5
unit_tests/builtins-coverage-5.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
float llCos( float theta )
|
||||
integer llModPow( integer a, integer b, integer c )
|
||||
event timer( )
|
||||
event no_sensor()
|
||||
event touch(integer x)
|
2
unit_tests/cat.py
Normal file
2
unit_tests/cat.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
import sys
|
||||
sys.stdout.write(sys.stdin.read())
|
9
unit_tests/coverage.suite/aux-funcs.lsl
Normal file
9
unit_tests/coverage.suite/aux-funcs.lsl
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Cover auxiliary functions.
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
llOwnerSay(llStringToBase64(llList2Key([TEXTURE_BLANK],0)));
|
||||
llOwnerSay(llStringToBase64(llList2Key([(key)TEXTURE_BLANK],0)));
|
||||
}
|
||||
}
|
8
unit_tests/coverage.suite/aux-funcs.out
Normal file
8
unit_tests/coverage.suite/aux-funcs.out
Normal file
|
@ -0,0 +1,8 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
llOwnerSay("NTc0OGRlY2MtZjYyOS00NjFjLTlhMzYtYTM1YTIyMWZlMjFm");
|
||||
llOwnerSay("NTc0OGRlY2MtZjYyOS00NjFjLTlhMzYtYTM1YTIyMWZlMjFm");
|
||||
}
|
||||
}
|
9
unit_tests/coverage.suite/declare-zero.lsl
Normal file
9
unit_tests/coverage.suite/declare-zero.lsl
Normal file
|
@ -0,0 +1,9 @@
|
|||
integer a = 0;
|
||||
float f = 0.0;
|
||||
vector v = <0.,0.,0.>;
|
||||
rotation r = <0.,0.,0.,1.>;
|
||||
key k = "";
|
||||
string s = "";
|
||||
list l = [];
|
||||
|
||||
default{state_entry(){}}
|
14
unit_tests/coverage.suite/declare-zero.out
Normal file
14
unit_tests/coverage.suite/declare-zero.out
Normal file
|
@ -0,0 +1,14 @@
|
|||
integer a;
|
||||
float f = 0;
|
||||
vector v = <0, 0, 0>;
|
||||
rotation r = <0, 0, 0, 1>;
|
||||
key k = "";
|
||||
string s = "";
|
||||
list l = [];
|
||||
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/declare-zero.run
Normal file
1
unit_tests/coverage.suite/declare-zero.run
Normal file
|
@ -0,0 +1 @@
|
|||
./main.py - -O -dcr
|
1
unit_tests/coverage.suite/existing-filename.lsl
Normal file
1
unit_tests/coverage.suite/existing-filename.lsl
Normal file
|
@ -0,0 +1 @@
|
|||
default{no_sensor(){}}
|
6
unit_tests/coverage.suite/existing-filename.out
Normal file
6
unit_tests/coverage.suite/existing-filename.out
Normal file
|
@ -0,0 +1,6 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/existing-filename.run
Normal file
1
unit_tests/coverage.suite/existing-filename.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py unit_tests/coverage.suite/existing-filename.lsl
|
18
unit_tests/coverage.suite/fndata-change.lsl
Normal file
18
unit_tests/coverage.suite/fndata-change.lsl
Normal file
|
@ -0,0 +1,18 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
llModPow(5, 7, 3);
|
||||
llCos(5);
|
||||
}
|
||||
|
||||
// this one should be kept, as it's not marked as SEF in the test data
|
||||
no_sensor()
|
||||
{
|
||||
}
|
||||
|
||||
// this one should disappear
|
||||
touch(integer k)
|
||||
{
|
||||
}
|
||||
}
|
11
unit_tests/coverage.suite/fndata-change.out
Normal file
11
unit_tests/coverage.suite/fndata-change.out
Normal file
|
@ -0,0 +1,11 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
llCos(5);
|
||||
}
|
||||
|
||||
no_sensor()
|
||||
{
|
||||
}
|
||||
}
|
2
unit_tests/coverage.suite/fndata-change.run
Normal file
2
unit_tests/coverage.suite/fndata-change.run
Normal file
|
@ -0,0 +1,2 @@
|
|||
main.py -b unit_tests/builtins-coverage-5.txt \
|
||||
-L unit_tests/fndata-coverage-5.txt -
|
16
unit_tests/coverage.suite/formatting.lsl
Normal file
16
unit_tests/coverage.suite/formatting.lsl
Normal file
|
@ -0,0 +1,16 @@
|
|||
e(){}
|
||||
integer a;
|
||||
integer b;
|
||||
f(){}
|
||||
g(){}
|
||||
integer c;
|
||||
integer d;
|
||||
h(){}
|
||||
default
|
||||
{
|
||||
timer() {}
|
||||
touch(integer n) {}
|
||||
touch_start(integer n) {}
|
||||
touch_end(integer n) {}
|
||||
}
|
||||
state s2{timer(){}}
|
47
unit_tests/coverage.suite/formatting.out
Normal file
47
unit_tests/coverage.suite/formatting.out
Normal file
|
@ -0,0 +1,47 @@
|
|||
e()
|
||||
{
|
||||
}
|
||||
|
||||
integer a;
|
||||
integer b;
|
||||
|
||||
f()
|
||||
{
|
||||
}
|
||||
|
||||
g()
|
||||
{
|
||||
}
|
||||
|
||||
integer c;
|
||||
integer d;
|
||||
|
||||
h()
|
||||
{
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
}
|
||||
|
||||
touch(integer n)
|
||||
{
|
||||
}
|
||||
|
||||
touch_start(integer n)
|
||||
{
|
||||
}
|
||||
|
||||
touch_end(integer n)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
state s2
|
||||
{
|
||||
timer()
|
||||
{
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/formatting.run
Normal file
1
unit_tests/coverage.suite/formatting.run
Normal file
|
@ -0,0 +1 @@
|
|||
./main.py --prettify -O clear -
|
2
unit_tests/coverage.suite/help-options.err
Normal file
2
unit_tests/coverage.suite/help-options.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
REGEX
|
||||
ProgName -O -DCR,\+BreakCont scriptname\.lsl
|
1
unit_tests/coverage.suite/help-options.run
Normal file
1
unit_tests/coverage.suite/help-options.run
Normal file
|
@ -0,0 +1 @@
|
|||
ProgName -O help
|
9
unit_tests/coverage.suite/include-header.lsl
Normal file
9
unit_tests/coverage.suite/include-header.lsl
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Test inclusion of headers and invalidation of comments
|
||||
/*
|
||||
|
||||
blah
|
||||
/|*
|
||||
/||*
|
||||
|
||||
*/
|
||||
default{timer(){}}
|
24
unit_tests/coverage.suite/include-header.out
Normal file
24
unit_tests/coverage.suite/include-header.out
Normal file
|
@ -0,0 +1,24 @@
|
|||
REGEX
|
||||
//start_unprocessed_text
|
||||
/\*// Test inclusion of headers and invalidation of comments
|
||||
/\*
|
||||
|
||||
blah
|
||||
/\|\|\*
|
||||
/\|\|\|\*
|
||||
|
||||
\*\|/
|
||||
default\{timer\(\)\{\}\}
|
||||
\*/
|
||||
//end_unprocessed_text
|
||||
//nfo_preprocessor_version 0
|
||||
//program_version LSL PyOptimizer .* - Sei Lisa
|
||||
//mono
|
||||
|
||||
// Generated on 20.*Z
|
||||
default
|
||||
\{
|
||||
timer\(\)
|
||||
\{
|
||||
\}
|
||||
\}
|
1
unit_tests/coverage.suite/include-header.run
Normal file
1
unit_tests/coverage.suite/include-header.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -T -H --avname=Sei\ Lisa --shortname=script.lsl -
|
49
unit_tests/coverage.suite/inline-1.lsl
Normal file
49
unit_tests/coverage.suite/inline-1.lsl
Normal file
|
@ -0,0 +1,49 @@
|
|||
f1() inline
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
|
||||
f2(integer f2param) inline
|
||||
{
|
||||
llOwnerSay("f2:" + (string)f2param);
|
||||
}
|
||||
|
||||
vector f3(integer f3p1, string f3p2) inline
|
||||
{
|
||||
f2(f3p1);
|
||||
integer f3p1; // test shading the parameter
|
||||
{
|
||||
jump x;
|
||||
llOwnerSay("f3:" + (string)f3p1 + f3p2);
|
||||
}
|
||||
@x;
|
||||
if (f3p2 != "") return <1,1,1>;
|
||||
do ; while (f4());
|
||||
return <0,0,0>;
|
||||
}
|
||||
|
||||
integer f4() inline
|
||||
{
|
||||
return llGetLinkNumber();
|
||||
}
|
||||
|
||||
say(string s) inline
|
||||
{
|
||||
llOwnerSay(s);
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
f1();
|
||||
if (1) f1();
|
||||
f2(3);
|
||||
if (f3(4, "x") == ZERO_VECTOR) llOwnerSay("ok");
|
||||
}
|
||||
|
||||
timer()
|
||||
{
|
||||
say("hi");
|
||||
}
|
||||
}
|
71
unit_tests/coverage.suite/inline-1.out
Normal file
71
unit_tests/coverage.suite/inline-1.out
Normal file
|
@ -0,0 +1,71 @@
|
|||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
if (1)
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
{
|
||||
integer f2param = 3;
|
||||
{
|
||||
llOwnerSay("f2:" + (string)f2param);
|
||||
}
|
||||
}
|
||||
vector ___ret__00001;
|
||||
{
|
||||
integer f3p1 = 4;
|
||||
string f3p2 = "x";
|
||||
{
|
||||
{
|
||||
integer f2param = f3p1;
|
||||
{
|
||||
llOwnerSay("f2:" + (string)f2param);
|
||||
}
|
||||
}
|
||||
integer f3p1;
|
||||
{
|
||||
jump ___lbl__00005;
|
||||
llOwnerSay("f3:" + (string)f3p1 + f3p2);
|
||||
}
|
||||
@___lbl__00005;
|
||||
if (f3p2 != "")
|
||||
{
|
||||
___ret__00001 = <1, 1, 1>;
|
||||
jump ___rtl__00004;
|
||||
}
|
||||
integer ___ret__00002;
|
||||
{
|
||||
{
|
||||
___ret__00002 = llGetLinkNumber();
|
||||
jump ___rtl__00007;
|
||||
}
|
||||
}
|
||||
@___rtl__00007;
|
||||
do
|
||||
;
|
||||
while (___ret__00002);
|
||||
{
|
||||
___ret__00001 = <0, 0, 0>;
|
||||
jump ___rtl__00004;
|
||||
}
|
||||
}
|
||||
}
|
||||
@___rtl__00004;
|
||||
if (___ret__00001 == <0., 0., 0.>)
|
||||
llOwnerSay("ok");
|
||||
}
|
||||
|
||||
timer()
|
||||
{
|
||||
{
|
||||
string s = "hi";
|
||||
{
|
||||
llOwnerSay(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/inline-1.run
Normal file
1
unit_tests/coverage.suite/inline-1.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -y -O clear,inline -
|
1
unit_tests/coverage.suite/inline-2.err
Normal file
1
unit_tests/coverage.suite/inline-2.err
Normal file
|
@ -0,0 +1 @@
|
|||
EExpansionLoop: Loop found in expansion of inline functions
|
19
unit_tests/coverage.suite/inline-2.lsl
Normal file
19
unit_tests/coverage.suite/inline-2.lsl
Normal file
|
@ -0,0 +1,19 @@
|
|||
f1() inline
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
f2();
|
||||
}
|
||||
|
||||
f2() inline
|
||||
{
|
||||
llOwnerSay("f2");
|
||||
f1();
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
f1();
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/inline-2.run
Normal file
1
unit_tests/coverage.suite/inline-2.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,inline -
|
11
unit_tests/coverage.suite/inline-3.lsl
Normal file
11
unit_tests/coverage.suite/inline-3.lsl
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Test inline, by Sei Lisa
|
||||
say(string s) inline
|
||||
{
|
||||
llOwnerSay(s);
|
||||
}
|
||||
|
||||
default{timer(){
|
||||
|
||||
say("hey");
|
||||
|
||||
}}
|
11
unit_tests/coverage.suite/inline-3.out
Normal file
11
unit_tests/coverage.suite/inline-3.out
Normal file
|
@ -0,0 +1,11 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
{
|
||||
{
|
||||
llOwnerSay("hey");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
unit_tests/coverage.suite/inline-4.lsl
Normal file
49
unit_tests/coverage.suite/inline-4.lsl
Normal file
|
@ -0,0 +1,49 @@
|
|||
f1() inline
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
|
||||
f2(integer f2param) inline
|
||||
{
|
||||
llOwnerSay("f2:" + (string)f2param);
|
||||
}
|
||||
|
||||
vector f3(integer f3p1, string f3p2) inline
|
||||
{
|
||||
f2(f3p1);
|
||||
integer f3p1; // test shading the parameter
|
||||
{
|
||||
jump x;
|
||||
llOwnerSay("f3:" + (string)f3p1 + f3p2);
|
||||
}
|
||||
@x;
|
||||
if (f3p2 != "") return <1,1,1>;
|
||||
do ; while (f4());
|
||||
return <0,0,0>;
|
||||
}
|
||||
|
||||
integer f4() inline
|
||||
{
|
||||
return llGetLinkNumber();
|
||||
}
|
||||
|
||||
say(string s) inline
|
||||
{
|
||||
llOwnerSay(s);
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
f1();
|
||||
if (1) f1();
|
||||
f2(3);
|
||||
if (f3(4, "x") == ZERO_VECTOR) llOwnerSay("ok");
|
||||
}
|
||||
|
||||
timer()
|
||||
{
|
||||
say("hi");
|
||||
}
|
||||
}
|
62
unit_tests/coverage.suite/inline-4.out
Normal file
62
unit_tests/coverage.suite/inline-4.out
Normal file
|
@ -0,0 +1,62 @@
|
|||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
{
|
||||
llOwnerSay("f1");
|
||||
}
|
||||
{
|
||||
{
|
||||
llOwnerSay("f2:" + "3");
|
||||
}
|
||||
}
|
||||
vector ___ret__00001 = <((float)0), ((float)0), ((float)0)>;
|
||||
{
|
||||
{
|
||||
{
|
||||
{
|
||||
llOwnerSay("f2:" + "4");
|
||||
}
|
||||
}
|
||||
{
|
||||
jump ___lbl__00005;
|
||||
}
|
||||
@___lbl__00005;
|
||||
{
|
||||
___ret__00001 = <((float)1), ((float)1), ((float)1)>;
|
||||
jump ___rtl__00004;
|
||||
}
|
||||
integer ___ret__00002;
|
||||
{
|
||||
{
|
||||
___ret__00002 = llGetLinkNumber();
|
||||
jump ___rtl__00007;
|
||||
}
|
||||
}
|
||||
@___rtl__00007;
|
||||
do
|
||||
;
|
||||
while (___ret__00002);
|
||||
{
|
||||
___ret__00001 = <((float)0), ((float)0), ((float)0)>;
|
||||
jump ___rtl__00004;
|
||||
}
|
||||
}
|
||||
}
|
||||
@___rtl__00004;
|
||||
if (___ret__00001 == <((float)0), ((float)0), ((float)0)>)
|
||||
llOwnerSay("ok");
|
||||
}
|
||||
|
||||
timer()
|
||||
{
|
||||
{
|
||||
{
|
||||
llOwnerSay("hi");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
unit_tests/coverage.suite/invalid-file.err
Normal file
2
unit_tests/coverage.suite/invalid-file.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
REGEX
|
||||
IOError: (?:\[Errno 21\] Is a directory|\[Errno 13\] Permission denied): 'unit_tests/coverage.suite/actually-a-dir.d'
|
1
unit_tests/coverage.suite/invalid-file.run
Normal file
1
unit_tests/coverage.suite/invalid-file.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py unit_tests/coverage.suite/actually-a-dir.d
|
3
unit_tests/coverage.suite/invalid-option.err
Normal file
3
unit_tests/coverage.suite/invalid-option.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
REGEX
|
||||
|
||||
Error: option --invalid-option not recognized
|
1
unit_tests/coverage.suite/invalid-option.run
Normal file
1
unit_tests/coverage.suite/invalid-option.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py --invalid-option
|
3
unit_tests/coverage.suite/linedir.err
Normal file
3
unit_tests/coverage.suite/linedir.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
default{timer(){x;}}
|
||||
^
|
||||
(Line 10 char 17): ERROR in "somefile.lsl": Name not defined within scope
|
4
unit_tests/coverage.suite/linedir.lsl
Normal file
4
unit_tests/coverage.suite/linedir.lsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
#line 1 "<stdin>"
|
||||
#line 1 "somefile.lsl"
|
||||
#line 10
|
||||
default{timer(){x;}}
|
1
unit_tests/coverage.suite/linedir.run
Normal file
1
unit_tests/coverage.suite/linedir.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O processpre -
|
9
unit_tests/coverage.suite/lsloptimizer.lsl
Normal file
9
unit_tests/coverage.suite/lsloptimizer.lsl
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Cover optimizer.Cast() using a call in lsldeadcode.
|
||||
default{timer(){
|
||||
|
||||
vector v;
|
||||
float f = llGetNumberOfSides() + v.x = 3;
|
||||
|
||||
llOwnerSay((string)[f]);
|
||||
|
||||
}}
|
8
unit_tests/coverage.suite/lsloptimizer.out
Normal file
8
unit_tests/coverage.suite/lsloptimizer.out
Normal file
|
@ -0,0 +1,8 @@
|
|||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
float f = ((float)3) + llGetNumberOfSides();
|
||||
llOwnerSay((string)((list)f));
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lsloptimizer.run
Normal file
1
unit_tests/coverage.suite/lsloptimizer.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -
|
2
unit_tests/coverage.suite/lsloutput-1.err
Normal file
2
unit_tests/coverage.suite/lsloutput-1.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
WARNING: Illegal combo: Key type inside a global list
|
||||
WARNING: A string contains a tab. Tabs are expanded to four spaces by the viewer when copy-pasting the code (disable this warning by disabling the 'warntabs' option).
|
37
unit_tests/coverage.suite/lsloutput-1.lsl
Normal file
37
unit_tests/coverage.suite/lsloutput-1.lsl
Normal file
|
@ -0,0 +1,37 @@
|
|||
list L = [llList2Key([llUnescapeURL("%09")], 0)];
|
||||
float f1 = -0.; // kept the same
|
||||
float f2 = -3.; // transformed to -3
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
float f0 = -15.5; // transformed to (float)-15.5
|
||||
vector v = <f0, f1, f2>;
|
||||
rotation r = <f0, f1, f2, f0>;
|
||||
integer i;
|
||||
while (llFrand(2) > 1)
|
||||
{
|
||||
llOwnerSay((string)(f0 + f1 + f2 + i));
|
||||
llSetPrimitiveParams(L);
|
||||
llSetPrimitiveParams(L);
|
||||
L = llGetPhysicsMaterial();
|
||||
f0 = llList2Float(L, 0);
|
||||
f1 = llList2Float(L, 1);
|
||||
f2 = llList2Float(L, 2);
|
||||
i = llList2Integer(L, i++);
|
||||
i = llList2Integer(L, i--);
|
||||
v = <f1, 0, 0>;
|
||||
r = <f1, 0, 0, 0>f1>;
|
||||
llSetRegionPos(v);
|
||||
llSetLocalRot(r);
|
||||
print(r.s);
|
||||
++i; --i;
|
||||
if (i)
|
||||
i >>= 1;
|
||||
else if (i > llFrand(3))
|
||||
return;
|
||||
L[2] = (integer)L[3];
|
||||
}
|
||||
}
|
||||
}
|
45
unit_tests/coverage.suite/lsloutput-1.out
Normal file
45
unit_tests/coverage.suite/lsloutput-1.out
Normal file
|
@ -0,0 +1,45 @@
|
|||
list lazy_list_set(list L, integer i, list v)
|
||||
{
|
||||
while ((L != []) < i)
|
||||
L = L + 0;
|
||||
return llListReplaceList(L, v, i, i);
|
||||
}
|
||||
|
||||
list L = [(key)" "];
|
||||
float f1 = -0.;
|
||||
float f2 = -3;
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
float f0 = ((float)-15.5);
|
||||
vector v = <f0, f1, f2>;
|
||||
rotation r = <f0, f1, f2, f0>;
|
||||
integer i;
|
||||
while (1 < llFrand(2))
|
||||
{
|
||||
llOwnerSay((string)(f0 + f1 + f2 + i));
|
||||
llSetPrimitiveParams(L);
|
||||
llSetPrimitiveParams(L);
|
||||
L = llGetPhysicsMaterial();
|
||||
f0 = llList2Float(L, 0);
|
||||
f1 = llList2Float(L, 1);
|
||||
f2 = llList2Float(L, 2);
|
||||
i = llList2Integer(L, i++);
|
||||
i = llList2Integer(L, i--);
|
||||
v = <f1, 0, 0>;
|
||||
r = <f1, 0, 0, (f1 < 0)>;
|
||||
llSetRegionPos(v);
|
||||
llSetLocalRot(r);
|
||||
print(r.s);
|
||||
++i;
|
||||
--i;
|
||||
if (i)
|
||||
i = i >> 1;
|
||||
else if (llFrand(3) < i)
|
||||
return;
|
||||
L = lazy_list_set(L, 2, (list)llList2Integer(L, 3));
|
||||
}
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lsloutput-1.run
Normal file
1
unit_tests/coverage.suite/lsloutput-1.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O foldtabs,lazylists -
|
8
unit_tests/coverage.suite/lsloutput-2.lsl
Normal file
8
unit_tests/coverage.suite/lsloutput-2.lsl
Normal file
|
@ -0,0 +1,8 @@
|
|||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
list L = llGetPhysicsMaterial();
|
||||
for(L[1];llFrand(2)<1;);
|
||||
}
|
||||
}
|
9
unit_tests/coverage.suite/lsloutput-2.out
Normal file
9
unit_tests/coverage.suite/lsloutput-2.out
Normal file
|
@ -0,0 +1,9 @@
|
|||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
list L = llGetPhysicsMaterial();
|
||||
for ((MISSING TYPE)L[1]; llFrand(2) < 1; )
|
||||
;
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lsloutput-2.run
Normal file
1
unit_tests/coverage.suite/lsloutput-2.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O -dcr,-constfold,lazylists -
|
1
unit_tests/coverage.suite/lsloutput-2.skp
Normal file
1
unit_tests/coverage.suite/lsloutput-2.skp
Normal file
|
@ -0,0 +1 @@
|
|||
This generates a runtime error now
|
56
unit_tests/coverage.suite/lslparse-1.lsl
Normal file
56
unit_tests/coverage.suite/lslparse-1.lsl
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Coverage tests of normal parsing
|
||||
f(){f();} // triggers FindSymbolPartial's last lines except the very last
|
||||
integer g(){if(1)return 1;else return 1;}
|
||||
integer T = TRUE;
|
||||
vector V = <1,-2,TRUE>;
|
||||
quaternion Q = <PI, 1.0, 0, 1>;
|
||||
list L = [];
|
||||
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
integer i;
|
||||
float f;
|
||||
vector v;
|
||||
// Parse_vector_rotation_tail
|
||||
<0,0,0.1>1>;
|
||||
// Parse_unary_postfix_expression
|
||||
ZERO_VECTOR;
|
||||
i = 1;
|
||||
i += i;
|
||||
f += i;
|
||||
i -= 1;
|
||||
i *= f;
|
||||
i /= 1;
|
||||
i %= 1;
|
||||
v *= i;
|
||||
++v.x;
|
||||
|
||||
// Parse_bitxor
|
||||
2^2;
|
||||
|
||||
// Parse_expression
|
||||
1&&1;
|
||||
|
||||
// Parse_statement
|
||||
@J;
|
||||
1;
|
||||
jump J;
|
||||
|
||||
// Scanner coverage
|
||||
quaternion q;
|
||||
1.3f;
|
||||
0x0;
|
||||
0x00000100000000;
|
||||
4294967296;
|
||||
42949672950;
|
||||
L"\t\"";
|
||||
|
||||
1 // Not a string delimiter because it has \ at EOL:
|
||||
" \
|
||||
// Not a string delimiter because it's the last double quote
|
||||
// in the file:
|
||||
";
|
||||
}
|
||||
}
|
51
unit_tests/coverage.suite/lslparse-1.out
Normal file
51
unit_tests/coverage.suite/lslparse-1.out
Normal file
|
@ -0,0 +1,51 @@
|
|||
f()
|
||||
{
|
||||
f();
|
||||
}
|
||||
|
||||
integer g()
|
||||
{
|
||||
if (1)
|
||||
return 1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
integer T = 1;
|
||||
vector V = <1, -2, 1>;
|
||||
rotation Q = <3.1415927, 1., 0, 1>;
|
||||
list L = [];
|
||||
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
integer i;
|
||||
float f;
|
||||
vector v;
|
||||
<0, 0, (0.1 > 1)>;
|
||||
<0., 0., 0.>;
|
||||
i = 1;
|
||||
i += i;
|
||||
f += i;
|
||||
i -= 1;
|
||||
i *= f;
|
||||
i /= 1;
|
||||
i %= 1;
|
||||
v *= i;
|
||||
++v.x;
|
||||
2 ^ 2;
|
||||
1 && 1;
|
||||
@J;
|
||||
1;
|
||||
jump J;
|
||||
rotation q;
|
||||
1.3;
|
||||
0;
|
||||
-1;
|
||||
-1;
|
||||
-1;
|
||||
"\" \"";
|
||||
1;
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-1.run
Normal file
1
unit_tests/coverage.suite/lslparse-1.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -y -O clear -
|
57
unit_tests/coverage.suite/lslparse-2.lsl
Normal file
57
unit_tests/coverage.suite/lslparse-2.lsl
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Test the extra features of the parser, to complete coverage.
|
||||
string S = "a" "b"; // juxtaposition in globals
|
||||
f(){}
|
||||
integer f(){return 1;}
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
// String juxtaposition coverage
|
||||
"a" "b";
|
||||
|
||||
// Explicit cast and extended cast coverage
|
||||
integer i;
|
||||
float f;
|
||||
list L;
|
||||
f += i;
|
||||
L += (integer)(float)i;
|
||||
i = ~(integer)-2*3;
|
||||
i = ~(integer)-2.*3;
|
||||
i = ~(integer)-i*3;
|
||||
|
||||
// AllowKeyConcat coverage
|
||||
""+(key)"";
|
||||
(key)""+"";
|
||||
|
||||
// Parse_statement with duplicate labels.
|
||||
@J;
|
||||
|
||||
// does_something() coverage
|
||||
switch(1)
|
||||
{
|
||||
{1;}
|
||||
}
|
||||
|
||||
// loops, switch and break/continue
|
||||
while (1) {break;for (;2;) {continue;break;} continue;}
|
||||
do { continue; break 1; } while (1);
|
||||
jump x;
|
||||
while (1) @x;
|
||||
jump y;
|
||||
for (;1;) @y;
|
||||
jump z;
|
||||
do @z; while (0);
|
||||
|
||||
switch(1.0)
|
||||
{
|
||||
case 1: {1;}
|
||||
}
|
||||
switch(1)
|
||||
{
|
||||
default {}
|
||||
}
|
||||
|
||||
while (1) continue;
|
||||
while (1) while (1) while (1) continue 3;
|
||||
}
|
||||
}
|
93
unit_tests/coverage.suite/lslparse-2.out
Normal file
93
unit_tests/coverage.suite/lslparse-2.out
Normal file
|
@ -0,0 +1,93 @@
|
|||
string S = "ab";
|
||||
|
||||
integer f()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
timer()
|
||||
{
|
||||
"ab";
|
||||
integer i;
|
||||
float f;
|
||||
list L;
|
||||
f += (float)i;
|
||||
L += (list)((integer)((float)i));
|
||||
i = (~(integer)-2) * 3;
|
||||
i = (~(integer)-2.) * 3;
|
||||
i = (~(integer)(-i)) * 3;
|
||||
"" + (string)((key)"");
|
||||
(string)((key)"") + "";
|
||||
@J;
|
||||
{
|
||||
jump J_autoGen00001;
|
||||
{
|
||||
1;
|
||||
}
|
||||
@J_autoGen00001;
|
||||
}
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
jump J_autoGen00002;
|
||||
{
|
||||
for (; 2; )
|
||||
{
|
||||
jump J_autoGen00005;
|
||||
jump J_autoGen00004;
|
||||
@J_autoGen00005;
|
||||
}
|
||||
@J_autoGen00004;
|
||||
}
|
||||
jump J_autoGen00003;
|
||||
@J_autoGen00003;
|
||||
}
|
||||
@J_autoGen00002;
|
||||
}
|
||||
{
|
||||
do
|
||||
{
|
||||
jump J_autoGen00007;
|
||||
jump J_autoGen00006;
|
||||
@J_autoGen00007;
|
||||
}
|
||||
while (1);
|
||||
@J_autoGen00006;
|
||||
}
|
||||
jump x;
|
||||
while (1)
|
||||
@x;
|
||||
jump y;
|
||||
for (; 1; )
|
||||
@y;
|
||||
jump z;
|
||||
do
|
||||
@z;
|
||||
while (0);
|
||||
{
|
||||
if (1. == (float)1)
|
||||
jump J_autoGen00015;
|
||||
jump J_autoGen00014;
|
||||
@J_autoGen00015;
|
||||
{
|
||||
1;
|
||||
}
|
||||
@J_autoGen00014;
|
||||
}
|
||||
{
|
||||
{
|
||||
}
|
||||
}
|
||||
while (1)
|
||||
;
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
while (1)
|
||||
jump J_autoGen00022;
|
||||
@J_autoGen00022;
|
||||
}
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-2.run
Normal file
1
unit_tests/coverage.suite/lslparse-2.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,allowmultistrings,enableswitch,explicitcast,extendedassignment,extendedtypecast,allowkeyconcat,duplabels,processpre,breakcont,funcoverride -
|
3
unit_tests/coverage.suite/lslparse-3.lsl
Normal file
3
unit_tests/coverage.suite/lslparse-3.lsl
Normal file
|
@ -0,0 +1,3 @@
|
|||
default{ev(){
|
||||
list L = LIST_CONSTANT;
|
||||
}}
|
7
unit_tests/coverage.suite/lslparse-3.out
Normal file
7
unit_tests/coverage.suite/lslparse-3.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
default
|
||||
{
|
||||
ev()
|
||||
{
|
||||
list L = [];
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-3.run
Normal file
1
unit_tests/coverage.suite/lslparse-3.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -b unit_tests/builtins-coverage-1.txt -L unit_tests/fndata-coverage-3.txt -O -dcr -
|
25
unit_tests/coverage.suite/lslparse-4.err
Normal file
25
unit_tests/coverage.suite/lslparse-4.err
Normal file
|
@ -0,0 +1,25 @@
|
|||
WARNING: Key constants not supported in unit_tests/builtins-coverage-4.txt, line 1: const key a="\t"
|
||||
WARNING: Event at line 3 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: ev
|
||||
WARNING: Function at line 5 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: x
|
||||
WARNING: Invalid type in unit_tests/builtins-coverage-4.txt, line 6: blah
|
||||
WARNING: Invalid type in unit_tests/builtins-coverage-4.txt, line 7: unknown
|
||||
WARNING: Syntax error in unit_tests/builtins-coverage-4.txt, line 8
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 9: const vector a = <4,5,3,2>
|
||||
WARNING: Global at line 10 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: a
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 10: const vector a = <4,5,3,2
|
||||
WARNING: Global at line 11 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: a
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 11: const vector a = <x,4,3>
|
||||
WARNING: Global at line 12 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: a
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 12: const vector a = <4,x,3>
|
||||
WARNING: Global at line 13 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: a
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 13: const vector a = <3,4,x>
|
||||
WARNING: Global at line 14 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: a
|
||||
WARNING: Invalid vector/rotation syntax in unit_tests/builtins-coverage-4.txt line 14: const rotation a = <3,4,4,x>
|
||||
WARNING: Invalid string in unit_tests/builtins-coverage-4.txt line 17: const string v="
|
||||
WARNING: Global at line 18 was already defined in unit_tests/builtins-coverage-4.txt, overwriting: q
|
||||
WARNING: Invalid type in unit_tests/builtins-coverage-4.txt, line 19: unknown
|
||||
WARNING: Non-empty list constants not supported in unit_tests/builtins-coverage-4.txt, line 20: const list L = [1]
|
||||
WARNING: Invalid list value in unit_tests/builtins-coverage-4.txt, line 21: const list L2 = [
|
||||
|
||||
^
|
||||
(Line 1 char 1): ERROR: Unexpected EOF
|
0
unit_tests/coverage.suite/lslparse-4.lsl
Normal file
0
unit_tests/coverage.suite/lslparse-4.lsl
Normal file
1
unit_tests/coverage.suite/lslparse-4.run
Normal file
1
unit_tests/coverage.suite/lslparse-4.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -b unit_tests/builtins-coverage-4.txt -L unit_tests/fndata-coverage-4.txt -O -dcr,-processpre -
|
3
unit_tests/coverage.suite/lslparse-err-1.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-1.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
integer a;
|
||||
^
|
||||
(Line 2 char 10): ERROR: Name previously declared within scope
|
2
unit_tests/coverage.suite/lslparse-err-1.lsl
Normal file
2
unit_tests/coverage.suite/lslparse-err-1.lsl
Normal file
|
@ -0,0 +1,2 @@
|
|||
integer a;
|
||||
integer a;
|
1
unit_tests/coverage.suite/lslparse-err-1.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-1.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear - -y
|
3
unit_tests/coverage.suite/lslparse-err-10.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-10.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
default: ;
|
||||
^
|
||||
(Line 2 char 5): ERROR: 'default' used outside a 'switch' statement
|
3
unit_tests/coverage.suite/lslparse-err-10.lsl
Normal file
3
unit_tests/coverage.suite/lslparse-err-10.lsl
Normal file
|
@ -0,0 +1,3 @@
|
|||
x(){
|
||||
default: ;
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-10.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-10.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-11.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-11.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
case 1: ;
|
||||
^
|
||||
(Line 3 char 3): ERROR: 'case' used outside a 'switch' statement
|
4
unit_tests/coverage.suite/lslparse-err-11.lsl
Normal file
4
unit_tests/coverage.suite/lslparse-err-11.lsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
x()
|
||||
{
|
||||
case 1: ;
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-11.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-11.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-12.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-12.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
{case 1: ;}
|
||||
^
|
||||
(Line 5 char 10): ERROR: 'case' label only allowed at the main 'switch' block
|
7
unit_tests/coverage.suite/lslparse-err-12.lsl
Normal file
7
unit_tests/coverage.suite/lslparse-err-12.lsl
Normal file
|
@ -0,0 +1,7 @@
|
|||
x()
|
||||
{
|
||||
switch(1)
|
||||
{
|
||||
{case 1: ;}
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-12.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-12.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-13.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-13.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
{default:;}
|
||||
^
|
||||
(Line 5 char 10): ERROR: 'default' label only allowed at the main 'switch' block
|
7
unit_tests/coverage.suite/lslparse-err-13.lsl
Normal file
7
unit_tests/coverage.suite/lslparse-err-13.lsl
Normal file
|
@ -0,0 +1,7 @@
|
|||
x()
|
||||
{
|
||||
switch(1)
|
||||
{
|
||||
{default:;}
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-13.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-13.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-14.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-14.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
}
|
||||
^
|
||||
(Line 8 char 1): ERROR: multiple 'default' labels inside 'switch' statement
|
8
unit_tests/coverage.suite/lslparse-err-14.lsl
Normal file
8
unit_tests/coverage.suite/lslparse-err-14.lsl
Normal file
|
@ -0,0 +1,8 @@
|
|||
x()
|
||||
{
|
||||
switch(1)
|
||||
{
|
||||
default: ;;
|
||||
default: ;;
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-14.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-14.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-15.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-15.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
}
|
||||
^
|
||||
(Line 7 char 1): ERROR: Missing 'default:' label inside 'switch' statement; disable option 'errmissingdefault' to disable this error.
|
7
unit_tests/coverage.suite/lslparse-err-15.lsl
Normal file
7
unit_tests/coverage.suite/lslparse-err-15.lsl
Normal file
|
@ -0,0 +1,7 @@
|
|||
x()
|
||||
{
|
||||
switch(1)
|
||||
{
|
||||
case 1: ;;
|
||||
}
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-15.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-15.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch,errmissingdefault -
|
3
unit_tests/coverage.suite/lslparse-err-16.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-16.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
break;
|
||||
^
|
||||
(Line 3 char 5): ERROR: 'break' used outside a switch
|
4
unit_tests/coverage.suite/lslparse-err-16.lsl
Normal file
4
unit_tests/coverage.suite/lslparse-err-16.lsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
x()
|
||||
{
|
||||
break;
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-16.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-16.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,enableswitch -
|
3
unit_tests/coverage.suite/lslparse-err-17.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-17.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
break;
|
||||
^
|
||||
(Line 3 char 5): ERROR: 'break' used outside a loop
|
4
unit_tests/coverage.suite/lslparse-err-17.lsl
Normal file
4
unit_tests/coverage.suite/lslparse-err-17.lsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
x()
|
||||
{
|
||||
break;
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-17.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-17.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,breakcont -
|
3
unit_tests/coverage.suite/lslparse-err-18.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-18.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
continue;
|
||||
^
|
||||
(Line 3 char 5): ERROR: 'continue' used outside a loop
|
4
unit_tests/coverage.suite/lslparse-err-18.lsl
Normal file
4
unit_tests/coverage.suite/lslparse-err-18.lsl
Normal file
|
@ -0,0 +1,4 @@
|
|||
x()
|
||||
{
|
||||
continue;
|
||||
}
|
1
unit_tests/coverage.suite/lslparse-err-18.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-18.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,breakcont -
|
3
unit_tests/coverage.suite/lslparse-err-19.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-19.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
#define a \
|
||||
^
|
||||
(Line 1 char 1): ERROR: Preprocessor directive can't end in backslash. Activate the preprocessor or put everything in the same line.
|
3
unit_tests/coverage.suite/lslparse-err-19.lsl
Normal file
3
unit_tests/coverage.suite/lslparse-err-19.lsl
Normal file
|
@ -0,0 +1,3 @@
|
|||
#define a \
|
||||
|
||||
x(){}
|
1
unit_tests/coverage.suite/lslparse-err-19.run
Normal file
1
unit_tests/coverage.suite/lslparse-err-19.run
Normal file
|
@ -0,0 +1 @@
|
|||
main.py -O clear,processpre -
|
3
unit_tests/coverage.suite/lslparse-err-2.err
Normal file
3
unit_tests/coverage.suite/lslparse-err-2.err
Normal file
|
@ -0,0 +1,3 @@
|
|||
return 0;
|
||||
^
|
||||
(Line 2 char 8): ERROR: Return statement type doesn't match function return type
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue