import sys
import re
import os
import codecs
from .Phase1Result import *
from .PreprocessScope import *
from .Fixture import Fixture
from .TestCaseParser import TestCaseParser
from .PreprocessScopeParser import *
from .ClassDeclParser import ClassDeclParser
from .DataProviderParser import DataProviderParser
from .Message import *
testcase_re1 = re.compile( r'^\s*TEST\s*\(\s*(?P<testcaseName>.+)\s*\)\s*$', re.UNICODE)
testcase_re2 = re.compile( r'^\s*void\s+(?P<testcaseId>test[A-Za-z0-9_]+)\s*\(\s*(void)?\s*\)\s*(?P<rest>.*)\s*$')
testcase_re3 = re.compile( r'^\s*void\s+(?P<testcaseId>[A-Za-z_][A-Za-z0-9_]*)\s*\(\s*(void)?\s*\)\s*(?P<rest>.*)\s*$')
p_testcase_re1 = re.compile( r'^\s*PTEST\s*\(\s*.+\)\s*,\s*(?P<testcaseName>.+)\s*\)\s*$', re.UNICODE)
class_decl_re = re.compile(r'^\s*(struct|class)\s+[A-Za-z0-9_]+\s*(?P<rest>.*)$')
data_provider_re = re.compile(r'^\s*DATA_PROVIDER\s*\(\s*(?P<name>[A-Za-z0-9_]+)\s*,\s*(?P<items>[1-9][0-9]*)(?P<rest>(.*))\s*$')
def is_testcase_def(line):
matched = testcase_re1.match(line)
if matched:
return None, matched.group("testcaseName"), None, ""
matched = testcase_re2.match(line)
if matched:
return matched.group("testcaseId"), None, None, matched.group("rest")
matched = p_testcase_re1.match(line)
if matched:
return None, matched.group("testcaseName"), True, ""
return None
def is_data_provider(line):
matched = data_provider_re.match(line)
if matched:
return matched.group("name"), matched.group("items"), matched.group("rest")
return None
def is_class_decl(line):
matched = class_decl_re.match(line)
if matched:
return matched.group("rest")
return None
def might_be_testcase_def(line):
matched = testcase_re3.match(line)
if matched:
return matched.group("testcaseId"), None, None, matched.group("rest")
return None
class FixtureParser:
def __init__(self, name, file, line, annotations):
self.numberOfUnclosedBraces = 0
self.begin = True
self.end = None
self.done = None
self.file = file
self.line = line
self.annotations = []
self.container = Fixture(name, self.file, self.line, annotations)
def get_container(self):
return self.container
def __might_be_elem_def(self, content):
return might_be_testcase_def(content)
def __has_test_annotation(self):
for anno in self.annotations:
if anno.get_tag() in ["test"] : return True
return False
def __is_testcase_def(self, line):
id = self.__might_be_elem_def(line.get_content())
if id and self.__has_test_annotation():
return id
return is_testcase_def(line.get_content())
def should_parse_sub_scopes(self):
return True
def __verify_dup_annotation(self, annotation):
for anno in self.annotations:
if annotations.get_tag() == anno:
fatal(self.line, annotation, "duplicated annotation @" + annotation.get_tag())
def handle_tag(self, annotation):
self.__verify_dup_annotation(annotation)
self.annotations.append(annotation)
def __report_useless_annotations(self):
for anno in self.annotations:
warning(self.file, anno, "useless annotation @" + anno.get_tag())
self.annotations = []
def verify_scope(self, tag):
self.__report_useless_annotations()
return True
def get_elem_parser(self, container, file, line):
testcase = self.__is_testcase_def(line)
if testcase != None:
return self.__create_testcase_parser(testcase, container.get_scope(), file, line.get_line_number())
rest = is_class_decl(line.get_content())
if rest != None:
return self.__create_class_decl_parser(rest, file, line.get_line_number())
data_provider = is_data_provider(line.get_content())
if data_provider != None:
return DataProviderParser(data_provider, file, line.get_line_number())
return None
def __create_class_decl_parser(self, content, file, line):
return ClassDeclParser(content, file, line)
def __create_testcase_parser(self, elem_name, scope, file, line):
parser = TestCaseParser(elem_name, scope, file, line, self.annotations)
self.annotations = []
return parser
def get_type_name(self):
return "fixture"
def __handle_space(self, line, c):
if c.isspace():
return True
return None
def __handle_done(self, line, c):
if not self.done:
return None
fatal(self.file, line, "unexpected char '" + c + "'")
def __handle_begin(self, line, c):
if not self.begin:
return None
if c == '{':
self.numberOfUnclosedBraces = 1
self.begin = None
return True
report_expect_char(self.file, line, "{", c)
def __handle_end(self, line, c):
if not self.end:
return None
if c == ';':
self.done = True
return True
report_expect_char(self.file, line, ";", c)
def __handle_others(self, line, c):
if c == '{':
self.numberOfUnclosedBraces += 1
elif c == '}':
self.numberOfUnclosedBraces -= 1
if self.numberOfUnclosedBraces == 0:
self.end = True
def __handle_char(self, line, c):
self.__handle_space(line, c) or \
self.__handle_done(line, c) or \
self.__handle_begin(line, c) or \
self.__handle_end(line, c) or \
self.__handle_others(line, c)
def is_done(self):
if self.done: return self.container
return None
def parse_line(self, line):
self.__report_useless_annotations()
for c in line.get_content():
self.__handle_char(line, c)
return self.is_done()