Compare commits
4 Commits
5e8d3018d9
...
b4f4711f76
Author | SHA1 | Date |
---|---|---|
Ulrich Carmesin | b4f4711f76 | 2 years ago |
Ulrich Carmesin | f2537d7604 | 2 years ago |
Ulrich Carmesin | d04d6d9ffd | 2 years ago |
Ulrich Carmesin | 10ba241ddd | 2 years ago |
55 changed files with 1520 additions and 52 deletions
@ -0,0 +1,7 @@ |
|||
# ----------------- |
|||
|
|||
EXP_KEY_MISSING = "key is missing {}" |
|||
EXP_KEY_DOESNT_EXIST = "key {} doesnt exist in domain {}" |
|||
LIST_EXP_TEXT = [EXP_KEY_MISSING, EXP_KEY_DOESNT_EXIST] |
|||
LIST_EXP_CONST = ["EXP_KEY_MISSING", "EXP_KEY_DOESNT_EXIST"] |
|||
|
@ -0,0 +1,197 @@ |
|||
#!/usr/bin/python |
|||
# -*- coding: utf-8 -*- |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
# Author : Ulrich Carmesin |
|||
# Source : gitea.ucarmesin.de |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
import unittest |
|||
import inspect |
|||
import os |
|||
import json |
|||
import basic.program |
|||
import utils.path_tool |
|||
import utils.path_const as P |
|||
import utils.config_tool |
|||
import utils.data_const as D |
|||
import basic.toolHandling |
|||
import test.constants |
|||
import basic.component |
|||
import basic.constants as B |
|||
import utils.map_tool |
|||
import utils.file_tool |
|||
import test.testtools |
|||
import utils.tdata_tool |
|||
|
|||
HOME_PATH = test.constants.HOME_PATH |
|||
|
|||
conf = {} |
|||
# here you can select single testfunction for developping the tests |
|||
# "test_toolhandling", "test_parseSql" -> test of components |
|||
TEST_FUNCTIONS = ["test_02getIds", "test_03extractIds", "test_04getFieldVal", "test_05getValue", |
|||
"test_11mapTdata"] |
|||
TEST_FUNCTIONS = ["test_11mapTdata"] |
|||
verbose = False |
|||
|
|||
class MyTestCase(unittest.TestCase): |
|||
mymsg = "--------------------------------------------------------------" |
|||
|
|||
def test_03extractIds(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
res = utils.map_tool.extractIds(job, "1") |
|||
self.assertEqual(res, ["1"]) |
|||
res = utils.map_tool.extractIds(job, "1, 2") |
|||
self.assertEqual(res, "1,2".split(",")) |
|||
res = utils.map_tool.extractIds(job, "1-3") |
|||
self.assertEqual(res, "1,2,3".split(",")) |
|||
res = utils.map_tool.extractIds(job, "1, 3-6, 8") |
|||
self.assertEqual(res, "1,3,4,5,6,8".split(",")) |
|||
cnttest += 4 |
|||
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) |
|||
|
|||
|
|||
def test_02getIds(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
path = utils.config_tool.getConfigPath(P.KEY_TESTCASE, "TC0001", "", job) |
|||
tdata = utils.tdata_tool.getCsvSpec(job.m, path, D.CSV_SPECTYPE_DATA) |
|||
args = {} |
|||
args[B.DATA_NODE_DATA] = tdata |
|||
args[B.DATA_NODE_STEPS] = tdata[B.DATA_NODE_STEPS][0] |
|||
args[utils.map_tool.ACT_ID] = {} |
|||
args[utils.map_tool.ID_LIST] = {} |
|||
ids = {} |
|||
res = utils.map_tool.getIds(job, args, "msgid={_steps._nr}") |
|||
print(res) |
|||
self.assertEqual(res[0], "1") |
|||
self.assertIn("msgid", args[utils.map_tool.ID_LIST]) |
|||
cnttest += 1 |
|||
res = utils.map_tool.getIds(job, args, "sender={_data.person._sender(_steps._nr)}") |
|||
print(res) |
|||
self.assertEqual(res[0], "firma") |
|||
args[B.DATA_NODE_STEPS] = tdata[B.DATA_NODE_STEPS][1] |
|||
res = utils.map_tool.getIds(job, args, "msgid={_steps._nr}") |
|||
self.assertEqual(res[1], "2") |
|||
self.assertIn("msgid", args[utils.map_tool.ID_LIST]) |
|||
cnttest += 1 |
|||
args[utils.map_tool.ACT_ID]["msgid"] = "1" |
|||
res = utils.map_tool.getIds(job, args, "posid={_data.product._nr,_pos(msgid)}") |
|||
self.assertEqual(res[0], ("1", "4")) |
|||
self.assertEqual(res[1], ("1", "5")) |
|||
cnttest += 1 |
|||
compName = "testcrmdb" |
|||
args[B.DATA_NODE_COMP] = test.testtools.getComp(compName) |
|||
comp = args[B.DATA_NODE_COMP] |
|||
conf = utils.config_tool.getConfig(D.DDL_FILENAME, compName, "person") |
|||
comp.conf[B.DATA_NODE_DDL] = {} |
|||
comp.conf[B.DATA_NODE_DDL]["person"] = conf |
|||
res = utils.map_tool.getIds(job, args, "fields={_comp.ddl.person}") |
|||
print(res) |
|||
args[utils.map_tool.ACT_ID]["posid"] = ("1", "4") |
|||
res = utils.map_tool.getConditions(job, args, "{posid}") |
|||
print(res) |
|||
self.assertEqual(res[0], ("1", "4")) |
|||
#self.assertEqual(res[1], "4") |
|||
cnttest += 1 |
|||
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) |
|||
|
|||
|
|||
def test_04getFieldVal(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
path = utils.config_tool.getConfigPath(P.KEY_TESTCASE, "TC0001", "", job) |
|||
tdata = utils.tdata_tool.getCsvSpec(job.m, path, D.CSV_SPECTYPE_DATA) |
|||
condIds = [["1"]] |
|||
args = {} |
|||
args[B.DATA_NODE_DATA] = tdata |
|||
res = utils.map_tool.getFieldVal(job, args, "person", "_sender", condIds) |
|||
print(res) |
|||
condIds = [["1"], ["4"]] |
|||
res = utils.map_tool.getFieldVal(job, args, "product", "descript", condIds) |
|||
print(res) |
|||
|
|||
def test_05getValue(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
path = utils.config_tool.getConfigPath(P.KEY_TESTCASE, "TC0001", "", job) |
|||
tdata = utils.tdata_tool.getCsvSpec(job.m, path, D.CSV_SPECTYPE_DATA) |
|||
condIds = [["1"]] |
|||
args = {} |
|||
args[B.DATA_NODE_DATA] = tdata |
|||
args[B.DATA_NODE_STEPS] = tdata[B.DATA_NODE_STEPS][0] |
|||
args[utils.map_tool.ACT_ID] = {} |
|||
args[utils.map_tool.ID_LIST] = {} |
|||
#res = utils.map_tool.getValue(job, args, "msgid={_steps._nr}") |
|||
#-print(res) |
|||
#self.assertEqual(res, ['1']) |
|||
args[utils.map_tool.ACT_ID]["msgid"] = ['1'] |
|||
#res = utils.map_tool.getValue(job, args, "sender={_data.person._sender(msgid)}") |
|||
#self.assertEqual(res, ["firma"]) |
|||
#print(res) |
|||
print(args[utils.map_tool.ID_LIST]) |
|||
args[utils.map_tool.ACT_ID]["sender"] = "firma" |
|||
res = utils.map_tool.getValue(job, args, "{_catalog.sender.depart(sender)}") |
|||
self.assertEqual(res, "main") |
|||
res = utils.map_tool.getValue(job, args, "{_steps.args.action}") |
|||
print(res) |
|||
res = utils.map_tool.getValue(job, args, "{_par.tctime}") |
|||
print(res) |
|||
args[utils.map_tool.ACT_ID]["msgid"] = "1" |
|||
res = utils.map_tool.getValue(job, args, "{_data.person.famname(msgid)}") |
|||
print(res) |
|||
self.assertEqual(res, "Brecht") |
|||
args[utils.map_tool.ACT_ID]["msgid"] = "1" |
|||
# select row if field is missing |
|||
res = utils.map_tool.getValue(job, args, "{_data.person(msgid)}") |
|||
print(res) |
|||
res = utils.map_tool.getValue(job, args, "hier ist ein Text") |
|||
print(res) |
|||
# it is one row [{f_1: v_2, ...}] |
|||
|
|||
|
|||
def test_11mapTdata(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
comp = test.testtools.getComp("testrest") |
|||
path = os.path.join(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_COMPS], "testrest", "mapping-rest.yml") |
|||
mapping = utils.file_tool.readFileDict(path, job.m) |
|||
path = utils.config_tool.getConfigPath(P.KEY_TESTCASE, "TC0001", "", job) |
|||
tdata = utils.tdata_tool.getCsvSpec(job.m, path, D.CSV_SPECTYPE_DATA) |
|||
res = utils.map_tool.mapTdata(job, mapping, tdata, tdata[B.DATA_NODE_STEPS][1], comp) |
|||
print(res) |
|||
for format in ["xml", "yml", "json"]: |
|||
path = os.path.join(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_TDATA], "temp", "result-rest."+format) |
|||
print(path) |
|||
utils.file_tool.writeFileDict(job.m, path, res) |
|||
doc = json.dumps(res, indent=0) |
|||
print(doc) |
|||
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) |
|||
|
|||
|
|||
def test_zzz(self): |
|||
print(MyTestCase.mymsg) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
verbose = True |
|||
unittest.main() |
@ -0,0 +1,59 @@ |
|||
#!/usr/bin/python |
|||
# -*- coding: utf-8 -*- |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
# Author : Ulrich Carmesin |
|||
# Source : gitea.ucarmesin.de |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
import unittest |
|||
import inspect |
|||
import os |
|||
import basic.program |
|||
import utils.path_tool |
|||
import utils.path_const as P |
|||
import utils.config_tool |
|||
import utils.data_const as D |
|||
import basic.toolHandling |
|||
import test.constants |
|||
import basic.component |
|||
import basic.constants as B |
|||
import utils.file_abstract |
|||
import utils.file_tool |
|||
import test.testtools |
|||
import utils.tdata_tool |
|||
|
|||
HOME_PATH = test.constants.HOME_PATH |
|||
|
|||
conf = {} |
|||
# here you can select single testfunction for developping the tests |
|||
# "test_toolhandling", "test_parseSql" -> test of components |
|||
TEST_FUNCTIONS = ["test_11mapTdata"] |
|||
TEST_FUNCTIONS = ["test_05getValue"] |
|||
verbose = False |
|||
|
|||
class MyTestCase(unittest.TestCase): |
|||
mymsg = "--------------------------------------------------------------" |
|||
|
|||
|
|||
def test_11mapTdata(self): |
|||
global mymsg |
|||
actfunction = str(inspect.currentframe().f_code.co_name) |
|||
cnttest = 0 |
|||
if actfunction not in TEST_FUNCTIONS: |
|||
return |
|||
job = test.testtools.getJob() |
|||
comp = test.testtools.getComp("testrest") |
|||
path = os.path.join(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_COMPS], "testrest", "mapping-rest.yml") |
|||
mapping = utils.file_tool.readFileDict(path, job.m) |
|||
path = utils.config_tool.getConfigPath(P.KEY_TESTCASE, "TC0001", "", job) |
|||
tdata = utils.tdata_tool.getCsvSpec(job.m, path, D.CSV_SPECTYPE_DATA) |
|||
res = utils.file_abstract.mapTdata(job, mapping, tdata, tdata[B.DATA_NODE_STEPS][0], comp) |
|||
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) |
|||
|
|||
|
|||
def test_zzz(self): |
|||
print(MyTestCase.mymsg) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
verbose = True |
|||
unittest.main() |
@ -0,0 +1,375 @@ |
|||
#!/usr/bin/python |
|||
# -*- coding: utf-8 -*- |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
# Author : Ulrich Carmesin |
|||
# Source : gitea.ucarmesin.de |
|||
# --------------------------------------------------------------------------------------------------------- |
|||
import os |
|||
import re |
|||
import basic.program |
|||
import basic.catalog |
|||
import utils.config_tool |
|||
import basic.constants as B |
|||
import basic.toolHandling |
|||
import utils.data_const as D |
|||
import utils.file_tool |
|||
import utils.path_tool |
|||
import basic.catalog |
|||
|
|||
ACT_ID = "actid" |
|||
ID_LIST = "idlist" |
|||
MAP_ID = "_id" |
|||
MAP_FOR = "_foreach" |
|||
MAP_ROW = "_row" |
|||
MAP_FCTS = [ MAP_FOR, MAP_ID, MAP_ROW ] |
|||
MODUL_NAME = "map_tool" |
|||
|
|||
|
|||
def mapTdata(job, mapping, tdata, step, comp): |
|||
""" |
|||
initialize the mapping from testdata into the mapping-structure |
|||
:param job: |
|||
:param mapping: |
|||
:param tdata: |
|||
:param step: |
|||
:param comp: |
|||
:return: |
|||
""" |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
out = {} |
|||
path = "" |
|||
job.debug(verify, mapping) |
|||
args = {} |
|||
args[B.DATA_NODE_COMP] = comp |
|||
args[B.DATA_NODE_DATA] = tdata |
|||
args[B.DATA_NODE_STEPS] = step |
|||
args[ACT_ID] = {} |
|||
args[ID_LIST] = {} |
|||
out = mapElement(job, args, mapping, path, out) |
|||
job.debug(verify, ">>>>>>>>>>> \n"+str(out)) |
|||
return out |
|||
|
|||
|
|||
def mapElement(job, args, elem, path, out): |
|||
""" |
|||
recursive mapping with building the dict of the testdata |
|||
:param job: |
|||
:param args: |
|||
:param elem: |
|||
:param path: |
|||
:param out: |
|||
:return: |
|||
""" |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
job.debug(verify, "mapElem "+path+" id: "+str(args[ACT_ID])) |
|||
if isinstance(elem, dict): |
|||
job.debug(verify, "##### dict ") |
|||
nodes = [] |
|||
attrNodes = [] |
|||
leafNodes = [] |
|||
objNodes = [] |
|||
for k in elem: |
|||
if MAP_ID in elem[k] or MAP_FOR in elem[k]: |
|||
objNodes.append(k) |
|||
elif k[0:1] == '@' or k[0:1] == '#': |
|||
attrNodes.append(k) |
|||
else: |
|||
leafNodes.append(k) |
|||
job.debug(verify, "nodes "+str(attrNodes)+" - "+str(leafNodes)+" - "+str(objNodes)) |
|||
nodes = attrNodes + leafNodes + objNodes |
|||
for k in nodes: |
|||
# iterating this elem is declared inside of the elem |
|||
# like foreach but only one element |
|||
job.debug(verify, "# # "+k) |
|||
if MAP_ID in elem[k] or MAP_FOR in elem[k]: |
|||
job.debug(verify, "# + k in obj : val "+k) |
|||
if MAP_ID in elem[k]: |
|||
key = elem[k][MAP_ID][0:elem[k][MAP_ID].find("=")] |
|||
idlist = getIds(job, args, elem[k][MAP_ID]) |
|||
if len(idlist) > 1: |
|||
uniqueKeys = {} |
|||
for x in idlist: |
|||
uniqueKeys[x] = x |
|||
if len(uniqueKeys) > 1: |
|||
raise Exception("bei keyword _id there is only one element allowed "+str(idlist)) |
|||
else: |
|||
idlist = uniqueKeys.keys() |
|||
elif MAP_FOR in elem[k]: |
|||
key = elem[k][MAP_FOR][0:elem[k][MAP_FOR].find("=")] |
|||
idlist = getIds(job, args, elem[k][MAP_FOR]) |
|||
sublist = [] |
|||
a = path.split(",") |
|||
a.append(k) |
|||
npath = ",".join(a) |
|||
for id in idlist: |
|||
args[ACT_ID][key] = str(id) |
|||
if MAP_ROW in elem[k]: |
|||
row = getRow(job, args, elem[k][MAP_ROW]) |
|||
sublist.append(mapElement(job, args, elem[k], npath, {})) |
|||
out[k] = sublist |
|||
elif k == MAP_ID or k == MAP_FOR or k == MAP_ROW: |
|||
job.debug(verify, "# + k in MAP : continue "+k) |
|||
continue |
|||
else: |
|||
job.debug(verify, "# + k in leaf : val "+k) |
|||
a = path.split(",") |
|||
a.append(k) |
|||
npath = ",".join(a) |
|||
job.debug(verify, "mapElem - dict "+k) |
|||
out[k] = mapElement(job, args, elem[k], npath, {}) |
|||
elif isinstance(elem, list): |
|||
out = [] |
|||
i = 0 |
|||
for k in elem: |
|||
job.debug(verify, "mapElem - list "+str(k)) |
|||
a = path.split(",") |
|||
a.append(str(i)) |
|||
npath = ",".join(a) |
|||
out.append(mapElement(job, args, elem[i], path, {})) |
|||
i += 1 |
|||
else: |
|||
job.debug(verify, "mapElem - leaf " + elem) |
|||
|
|||
if elem[0:1] == "{" and elem[-1:] == "}": |
|||
elem = elem[1:-1] |
|||
out = toSimpleType(job, getValue(job, args, elem)) |
|||
return out |
|||
|
|||
|
|||
def toSimpleType(job, value): |
|||
if isinstance(value, (list, tuple)) and len(value) == 1: |
|||
return value[0] |
|||
return value |
|||
|
|||
def extractIds(job, idval): |
|||
ids = [] |
|||
if isinstance(idval, list) or isinstance(idval, tuple): |
|||
a = idval |
|||
else: |
|||
a = idval.split(",") |
|||
for k in a: |
|||
if "-" in k: |
|||
b = k.split("-") |
|||
for i in range(int(b[0].strip()), int(b[1].strip())+1): |
|||
ids.append(str(i).strip()) |
|||
elif isinstance(k, str): |
|||
ids.append(k.strip()) |
|||
else: |
|||
ids.append(k) |
|||
return ids |
|||
|
|||
|
|||
def getRow(job, args, fieldkey): |
|||
a = fieldkey.split(".") |
|||
row = getValue(job, args, fieldkey) |
|||
if B.DATA_NODE_ROW not in args: args[B.DATA_NODE_ROW] = {} |
|||
a[1] = a[1][0:a[1].find("(")] |
|||
args[B.DATA_NODE_ROW][a[1]] = row[0] |
|||
return row |
|||
|
|||
def getIds(job, args, fieldkey): |
|||
""" |
|||
sets the id resp list of ids into args[idlist] |
|||
the fieldkey has a formula like id={_source.table.field(condition)} |
|||
:param job: |
|||
:param args: |
|||
:param fieldky: |
|||
:return: |
|||
""" |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
job.debug(verify, "match = "+fieldkey) |
|||
out = [] |
|||
idfield = fieldkey |
|||
if re.match(r"(.+)\=(.+)", fieldkey): |
|||
res = re.search(r"(.+)\=(.+)", fieldkey) |
|||
idfield = res.group(1) |
|||
fieldkey = res.group(2) |
|||
if fieldkey[0:1] == "{" and fieldkey[-1:] == "}": |
|||
fieldkey = fieldkey[1:-1] |
|||
if "temp" not in args: args["temp"] = {} |
|||
i = 0 |
|||
while "(" in fieldkey and ")" in fieldkey: |
|||
innerCond = fieldkey[fieldkey.rfind("(")+1:fieldkey.find(")")] |
|||
if "." not in innerCond: |
|||
break |
|||
innerkey = "temp_"+str(i) |
|||
args["temp"][innerkey] = {} |
|||
args["temp"][innerkey]["idfield"] = idfield |
|||
args["temp"][innerkey]["fieldkey"] = fieldkey |
|||
innerlist = getIds(job, args, innerkey+"={"+innerCond+"}") |
|||
args[ACT_ID][innerkey] = ",".join(innerlist) |
|||
fieldkey = fieldkey.replace(innerCond, innerkey) |
|||
idfield = args["temp"][innerkey]["idfield"] |
|||
i += 1 |
|||
if i > 3: |
|||
raise Exception("too much searches "+str(args["temp"])) |
|||
val = getValue(job, args, fieldkey) |
|||
idlist = extractIds(job, val) |
|||
args[ID_LIST][idfield] = idlist |
|||
job.debug(verify, "idlist " + str(args[ID_LIST])) |
|||
return idlist |
|||
|
|||
|
|||
def getConditions(job, args, fieldkey): |
|||
""" |
|||
gets a list of condition-value |
|||
:param job: |
|||
:param args: |
|||
:param fieldkey: in formula (c_1, c_2, ..) |
|||
:return: [v_1} ..] |
|||
""" |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
while fieldkey[0:1] == "(" and fieldkey[-1:] == ")": |
|||
fieldkey = fieldkey[1:-1] |
|||
while fieldkey[0:1] == "{" and fieldkey[-1:] == "}": |
|||
fieldkey = fieldkey[1:-1] |
|||
out = [] |
|||
a = fieldkey.split(",") |
|||
if len(a) > 1: |
|||
job.m.logError("map-condition should not have more parts - use tupel "+fieldkey) |
|||
for k in a: |
|||
if "." in k: |
|||
raise Exception("Formatfehler in " + fieldkey) |
|||
job.debug(verify, "actid " + str(args[ACT_ID])) |
|||
idelem = {} |
|||
idelem[k] = args[ACT_ID][k] |
|||
out.append(args[ACT_ID][k]) |
|||
return out |
|||
|
|||
|
|||
def getValue(job, args, fieldkey): |
|||
""" |
|||
gets the value of the formula like {_source.table.field(condition)} |
|||
:param job: |
|||
:param args: |
|||
:param fieldkey: |
|||
:return: |
|||
""" |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
job.debug(verify, "getValue "+fieldkey) |
|||
while fieldkey[0:1] == "{" and fieldkey[-1:] == "}": |
|||
fieldkey = fieldkey[1:-1] |
|||
val = "" |
|||
idfield = "" |
|||
source = "" |
|||
table = "" |
|||
field = "" |
|||
cond = "" |
|||
condIds = [] |
|||
# special cases of id-management |
|||
# args[actid][xid] = actual id with name xid |
|||
# args[idlist][xid] = list of all ids with name xid |
|||
# a) declaration of the id : id={fielddefinition} |
|||
if re.match(r".+\=.+", fieldkey): |
|||
job.debug(verify, "getValue 222 " + fieldkey) |
|||
raise Exception("getIds sollte an passender Stelle direkt aufgerufen werden "+fieldkey) |
|||
return getIds(job, args, fieldkey) |
|||
# b) set of defined ids - neither fielddefinition nor a function |
|||
#elif "." not in fieldkey and "(" not in fieldkey or re.match(r"\(.+\)", fieldkey): |
|||
#print("getValue 226 " + fieldkey) |
|||
#raise Exception("getConditions sollte an passender Stelle direkt aufgerufen werden") |
|||
#return getConditions(job, args, fieldkey) |
|||
# fielddefinition with .-separated parts |
|||
b = fieldkey.split(".") |
|||
job.debug(verify, "match field "+fieldkey) |
|||
if re.match(r"(_.+)\..+\..+\(.+\)", fieldkey): |
|||
res = re.match(r"(_.+)\.(.+)\.(.+\(.+\))", fieldkey) |
|||
job.debug(verify, "match mit ()") |
|||
source = res.group(1) |
|||
table = res.group(2) |
|||
field = res.group(3) |
|||
#cond = res.group(4) |
|||
#condIds = getValue(job, args, cond) |
|||
elif len(b) == 1: |
|||
field = b[0] |
|||
elif len(b) == 2: |
|||
source = b[0] |
|||
field = b[1] |
|||
elif len(b) == 3: |
|||
source = b[0] |
|||
table = b[1] |
|||
field = b[2] |
|||
if re.match(r".+\(.+\)", field): |
|||
res = re.match(r"(.+)\((.+)\)", field) |
|||
field = res.group(1) |
|||
cond = res.group(2) |
|||
condIds = getConditions(job, args, cond) |
|||
job.debug(verify, source + " - " + table + " - " + field + " - " + cond + " : " + str(condIds)) |
|||
if source == B.DATA_NODE_ROW: |
|||
if table not in args[B.DATA_NODE_ROW]: |
|||
raise Exception("row not initialiazed for table "+table+" "+str(args[B.DATA_NODE_ROW])) |
|||
row = args[B.DATA_NODE_ROW][table] |
|||
val = row[field] |
|||
elif source == B.DATA_NODE_DATA: |
|||
job.debug(verify, "data " + b[1]) |
|||
if len(b) == 3: |
|||
job.debug(verify, table + ", " + field + ", " + cond + ", " + str(condIds)) |
|||
val = toSimpleType(job, getFieldVal(job, args, table, field, condIds)) |
|||
elif len(b) == 2: |
|||
job.debug(verify, table + ", " + field + ", " + cond + ", " + str(condIds)) |
|||
val = getTdataRow(job, args[B.DATA_NODE_DATA], field, condIds) |
|||
elif source == B.DATA_NODE_STEPS: |
|||
job.debug(verify, "steps " + table+" - "+ field) |
|||
if hasattr(args[B.DATA_NODE_STEPS], field): |
|||
val = getattr(args[B.DATA_NODE_STEPS], field) |
|||
elif hasattr(args[B.DATA_NODE_STEPS], table): |
|||
row = getattr(args[B.DATA_NODE_STEPS], table) |
|||
if field in row: |
|||
val = row[field] |
|||
elif source[1:] == B.DATA_NODE_PAR: |
|||
job.debug(verify, "par " + b[1]) |
|||
if getattr(job.par, b[1]): |
|||
val = getattr(job.par, b[1]) |
|||
elif source == B.DATA_NODE_CATALOG: |
|||
job.debug(verify, "catalog " + table+", "+ field) |
|||
if len(b) != 3: |
|||
job.debug(verify, "catalog-Fehler") |
|||
return "Fehler-145" |
|||
row = basic.catalog.Catalog.getInstance().getValue(table, args[ACT_ID][cond], job) |
|||
if isinstance(row, dict) and field in row: |
|||
val = row[field] |
|||
elif source[1:] == B.DATA_NODE_COMP: |
|||
job.debug(verify, "comp "+table+", "+field) |
|||
comp = args[B.DATA_NODE_COMP] |
|||
if table == B.DATA_NODE_DDL: |
|||
fields = comp.conf[B.DATA_NODE_DDL][field][B.DATA_NODE_HEADER] |
|||
val = ",".join(fields) |
|||
else: |
|||
val = fieldkey |
|||
job.debug(verify, "return val "+str(val)) |
|||
return val |
|||
|
|||
def getFieldVal(job, args, table, field, condIds): |
|||
out = [] |
|||
fields = field.split(",") |
|||
for row in getTdataRow(job, args[B.DATA_NODE_DATA], table, condIds): |
|||
if len(fields) == 1 and field in row: |
|||
out.append( str(row[field]).strip()) |
|||
else: |
|||
tup = tuple() |
|||
for f in fields: |
|||
if f in row: |
|||
t = tuple( str(row[f]).strip() ) |
|||
tup = tup + t |
|||
else: |
|||
raise Exception("field is missing in row "+f+", "+str(row)) |
|||
out.append(tup) |
|||
return out |
|||
|
|||
def getTdataRow(job, tdata, table, condIds): |
|||
verify = job.getDebugLevel(MODUL_NAME) |
|||
out = [] |
|||
idFields = {} |
|||
job.debug(verify, "getTdata "+str(condIds)) |
|||
for i in range(0, len(condIds)): |
|||
idFields[tdata[B.DATA_NODE_TABLES][table][B.DATA_NODE_HEADER][i]] = condIds[i] |
|||
job.debug(verify, "idFields "+str(idFields)) |
|||
for row in tdata[B.DATA_NODE_TABLES][table][B.DATA_NODE_DATA]: |
|||
i = 0 |
|||
for k in idFields: |
|||
for j in range(0, len(idFields[k])): |
|||
if row[k] == idFields[k][j]: |
|||
i += 1 |
|||
if i == len(idFields): |
|||
out.append(row) |
|||
return out |
@ -0,0 +1,8 @@ |
|||
#!/usr/bin/bash |
|||
# script to start development web in webflask - port 5000 |
|||
export FLASK_APP=webflask |
|||
export FLASK_DEBUG=1 |
|||
# flask init-db |
|||
|
|||
flask run |
|||
|
@ -0,0 +1,57 @@ |
|||
import os |
|||
from flask import Flask |
|||
|
|||
|
|||
def create_app(test_config=None): |
|||
# create and configure the app |
|||
app = Flask(__name__, instance_relative_config=True) |
|||
app.config.from_mapping( |
|||
SECRET_KEY='dev', |
|||
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), |
|||
) |
|||
|
|||
if test_config is None: |
|||
# load the instance config, if it exists, when not testing |
|||
app.config.from_pyfile('config.py', silent=True) |
|||
else: |
|||
# load the test config if passed in |
|||
app.config.from_mapping(test_config) |
|||
|
|||
# ensure the instance folder exists |
|||
try: |
|||
os.makedirs(app.instance_path) |
|||
except OSError: |
|||
pass |
|||
|
|||
from . import db |
|||
db.init_app(app) |
|||
from . import auth |
|||
from . import index |
|||
from . import testcase |
|||
from . import testsuite |
|||
from . import components |
|||
from . import reports |
|||
from . import environment |
|||
app.register_blueprint(auth.bp) |
|||
app.register_blueprint(index.bp) |
|||
app.register_blueprint(testcase.bp) |
|||
app.register_blueprint(testsuite.bp) |
|||
app.register_blueprint(components.bp) |
|||
app.register_blueprint(reports.bp) |
|||
app.register_blueprint(environment.bp) |
|||
|
|||
# a simple page that says hello |
|||
@app.route('/hello') |
|||
def hello(): |
|||
return 'Hello, World!' |
|||
|
|||
return app |
|||
|
|||
@app.route('/') |
|||
def index(): |
|||
return 'Index Page' |
|||
|
|||
@app.route('/index') |
|||
def index(): |
|||
return 'Index Page 2' |
|||
|
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('testcase', __name__, url_prefix='/testcase') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/overview.html') |
|||
|
@ -0,0 +1,92 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('auth', __name__, url_prefix='/auth') |
|||
|
|||
@bp.route('/login', methods=('GET', 'POST')) |
|||
def login(): |
|||
if request.method == 'POST': |
|||
username = request.form['username'] |
|||
password = request.form['password'] |
|||
db = get_db() |
|||
error = None |
|||
user = db.execute( |
|||
'SELECT * FROM user WHERE username = ?', (username,) |
|||
).fetchone() |
|||
|
|||
if user is None: |
|||
error = 'Incorrect username.' |
|||
elif not check_password_hash(user['password'], password): |
|||
error = 'Incorrect password.' |
|||
|
|||
if error is None: |
|||
session.clear() |
|||
session['user_id'] = user['id'] |
|||
return redirect(url_for('index')) |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('auth/login.html') |
|||
|
|||
@bp.route('/register', methods=('GET', 'POST')) |
|||
def register(): |
|||
if request.method == 'POST': |
|||
username = request.form['username'] |
|||
password = request.form['password'] |
|||
db = get_db() |
|||
error = None |
|||
|
|||
if not username: |
|||
error = 'Username is required.' |
|||
elif not password: |
|||
error = 'Password is required.' |
|||
|
|||
if error is None: |
|||
try: |
|||
db.execute( |
|||
"INSERT INTO user (username, password) VALUES (?, ?)", |
|||
(username, generate_password_hash(password)), |
|||
) |
|||
db.commit() |
|||
except db.IntegrityError: |
|||
error = f"User {username} is already registered." |
|||
else: |
|||
return redirect(url_for("auth.login")) |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('auth/register.html') |
|||
|
|||
@bp.before_app_request |
|||
def load_logged_in_user(): |
|||
user_id = session.get('user_id') |
|||
|
|||
if user_id is None: |
|||
g.user = None |
|||
else: |
|||
g.user = get_db().execute( |
|||
'SELECT * FROM user WHERE id = ?', (user_id,) |
|||
).fetchone() |
|||
|
|||
@bp.route('/logout') |
|||
def logout(): |
|||
session.clear() |
|||
return redirect(url_for('index')) |
|||
|
|||
def login_required(view): |
|||
@functools.wraps(view) |
|||
def wrapped_view(**kwargs): |
|||
if g.user is None: |
|||
return redirect(url_for('auth.login')) |
|||
|
|||
return view(**kwargs) |
|||
|
|||
return wrapped_view |
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('components', __name__, url_prefix='/components') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('components/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('components/overview.html') |
|||
|
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('testcase', __name__, url_prefix='/testcase') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/overview.html') |
|||
|
@ -0,0 +1,41 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/database/ |
|||
# ---------------------------------------------------------------------------- |
|||
import sqlite3 |
|||
|
|||
import click |
|||
from flask import current_app, g |
|||
from flask.cli import with_appcontext |
|||
|
|||
def init_db(): |
|||
db = get_db() |
|||
|
|||
with current_app.open_resource('schema.sql') as f: |
|||
db.executescript(f.read().decode('utf8')) |
|||
|
|||
def get_db(): |
|||
if 'db' not in g: |
|||
g.db = sqlite3.connect( |
|||
current_app.config['DATABASE'], |
|||
detect_types=sqlite3.PARSE_DECLTYPES |
|||
) |
|||
g.db.row_factory = sqlite3.Row |
|||
|
|||
return g.db |
|||
|
|||
|
|||
def close_db(e=None): |
|||
db = g.pop('db', None) |
|||
|
|||
if db is not None: |
|||
db.close() |
|||
|
|||
@click.command('init-db') |
|||
@with_appcontext |
|||
def init_db_command(): |
|||
"""Clear the existing data and create new tables.""" |
|||
init_db() |
|||
click.echo('Initialized the database.') |
|||
|
|||
def init_app(app): |
|||
app.teardown_appcontext(close_db) |
|||
app.cli.add_command(init_db_command) |
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('environment', __name__, url_prefix='/environment') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('environment/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('environment/overview.html') |
|||
|
@ -0,0 +1,23 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('index', __name__, url_prefix='/') |
|||
|
|||
@bp.route('/', methods=('GET', 'POST')) |
|||
def index(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('index.html') |
|||
|
|||
|
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('reports', __name__, url_prefix='/reports') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('reports/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('reports/overview.html') |
|||
|
@ -0,0 +1,17 @@ |
|||
DROP TABLE IF EXISTS user; |
|||
DROP TABLE IF EXISTS post; |
|||
|
|||
CREATE TABLE user ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|||
username TEXT UNIQUE NOT NULL, |
|||
password TEXT NOT NULL |
|||
); |
|||
|
|||
CREATE TABLE post ( |
|||
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|||
author_id INTEGER NOT NULL, |
|||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, |
|||
title TEXT NOT NULL, |
|||
body TEXT NOT NULL, |
|||
FOREIGN KEY (author_id) REFERENCES user (id) |
|||
); |
@ -0,0 +1,20 @@ |
|||
addEventListener("load", addCollaps); |
|||
function addCollaps() { |
|||
var coll = document.getElementsByClassName("collapsible"); |
|||
for (var c of coll) { |
|||
c.addEventListener("click", function() { |
|||
this.nextElementSibling.classList.toggle("collapsed"); |
|||
}); |
|||
} |
|||
} |
|||
// TODO : kann raus
|
|||
function loadJson(filename, callback) { |
|||
var xhr = XMLHttpRequest(); |
|||
xhr.onreadystatechange = function() { |
|||
if(this.readyState == 4 && this.status == 200) { |
|||
callback(JSON.parse(xhr.responseText)); |
|||
} |
|||
} |
|||
xhr.open(get, filename); |
|||
xhr.send(); |
|||
} |
@ -0,0 +1,31 @@ |
|||
html { font-family: sans-serif; background: #eee; padding: 1rem; } |
|||
body { max-width: 960px; margin: 0 auto; background: white; } |
|||
h1 { font-family: serif; color: #377ba8; margin: 1rem 0; } |
|||
a { color: #377ba8; } |
|||
hr { border: none; border-top: 1px solid lightgray; } |
|||
nav { background: lightgray; display: flex; align-items: center; padding: 0 0.5rem; } |
|||
nav h1 { flex: auto; margin: 0; } |
|||
nav h1 a { text-decoration: none; padding: 0.25rem 0.5rem; } |
|||
nav ul { display: flex; list-style: none; margin: 0; padding: 0; } |
|||
nav ul li a, nav ul li span, header .action { display: block; padding: 0.5rem; } |
|||
.content { padding: 0 1rem 1rem; } |
|||
.content > header { border-bottom: 1px solid lightgray; display: flex; align-items: flex-end; } |
|||
.content > header h1 { flex: auto; margin: 1rem 0 0.25rem 0; } |
|||
.flash { margin: 1em 0; padding: 1em; background: #cae6f6; border: 1px solid #377ba8; } |
|||
.post > header { display: flex; align-items: flex-end; font-size: 0.85em; } |
|||
.post > header > div:first-of-type { flex: auto; } |
|||
.post > header h1 { font-size: 1.5em; margin-bottom: 0; } |
|||
.post .about { color: slategray; font-style: italic; } |
|||
.post .body { white-space: pre-line; } |
|||
.content:last-child { margin-bottom: 0; } |
|||
.content form { margin: 1em 0; display: flex; flex-direction: column; } |
|||
.content label { font-weight: bold; margin-bottom: 0.5em; } |
|||
.content input, .content textarea { margin-bottom: 1em; } |
|||
.content textarea { min-height: 12em; resize: vertical; } |
|||
input.danger { color: #cc2f2e; } |
|||
input[type=submit] { align-self: start; min-width: 10em; } |
|||
.collapsible { background-color: #777; color: white; cursor: pointer; padding: 5px; width: 100%; |
|||
border: none; text-align: left; outline: none; font-size: 15px; } |
|||
.collapsed { padding: 0 18px; display: none; overflow: hidden; } |
|||
.active, .collapsible:hover { background-color: #ccc; } |
|||
|
@ -0,0 +1,9 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein</p> |
|||
{% endblock %} |
@ -0,0 +1,16 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Log In{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<form method="post"> |
|||
<label for="username">Username</label> |
|||
<input name="username" id="username" required> |
|||
<label for="password">Password</label> |
|||
<input type="password" name="password" id="password" required> |
|||
<input type="submit" value="Log In"> |
|||
</form> |
|||
<p>hiermit sollte ein Workspace geoeffnet werden <br/> - bestehend aus eigenem testdata-repo und components-repo.</p> |
|||
{% endblock %} |
@ -0,0 +1,17 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Register{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<form method="post"> |
|||
<label for="username">Username</label> |
|||
<input name="username" id="username" required> |
|||
<label for="password">Password</label> |
|||
<input type="password" name="password" id="password" required> |
|||
<input type="submit" value="Register"> |
|||
</form> |
|||
<p>Durch das Registrieren sollte ein Workspace angelegt werden <br/> |
|||
- bestehend aus eine testdata-repo und einem components-repo </p> |
|||
{% endblock %} |
@ -0,0 +1,40 @@ |
|||
<!doctype html> |
|||
<head> |
|||
<title>{% block title %}{% endblock %} - Datest</title> |
|||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> |
|||
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script> |
|||
<script> |
|||
var jsonData = "{{ get_json() }}"; |
|||
</script> |
|||
</head> |
|||
<body> |
|||
<nav> |
|||
<h1>Datest</h1> |
|||
<ul> |
|||
{% if g.user %} |
|||
<li><span>{{ g.user['username'] }}</span> |
|||
<li><a href="{{ url_for('testcase.overview') }}">Testcase</a> |
|||
<li><a href="{{ url_for('testsuite.overview') }}">Testsuite</a> |
|||
<li><a href="{{ url_for('reports.overview') }}">Reports</a> |
|||
<li><a href="{{ url_for('components.overview') }}">Components</a> |
|||
<li><a href="{{ url_for('auth.logout') }}">Log Out</a> |
|||
{% else %} |
|||
<li><a href="{{ url_for('testcase.overview') }}">Testcase</a> |
|||
<li><a href="{{ url_for('testsuite.overview') }}">Testsuite</a> |
|||
<li><a href="{{ url_for('reports.overview') }}">Reports</a> |
|||
<li><a href="{{ url_for('components.overview') }}">Components</a> |
|||
<li><a href="{{ url_for('auth.register') }}">Register</a> |
|||
<li><a href="{{ url_for('auth.login') }}">Log In</a> |
|||
{% endif %} |
|||
</ul> |
|||
</nav> |
|||
<section class="content"> |
|||
<header> |
|||
{% block header %}{% endblock %} |
|||
</header> |
|||
{% for message in get_flashed_messages() %} |
|||
<div class="flash">{{ message }}</div> |
|||
{% endfor %} |
|||
{% block content %}{% endblock %} |
|||
</section> |
|||
</body> |
@ -0,0 +1,9 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein</p> |
|||
{% endblock %} |
@ -0,0 +1,9 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein</p> |
|||
{% endblock %} |
@ -0,0 +1,12 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein:<br/> |
|||
- info Datest allgemein -> ucarmesin.de/joomla |
|||
- Bereiche Testfaelle (anzahl) |
|||
- letzte Updates (git log) </p> |
|||
{% endblock %} |
@ -0,0 +1,9 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein</p> |
|||
{% endblock %} |
@ -0,0 +1,32 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein. <br/> |
|||
Bei angemeldetem User kann auf das eigene Repo schreibend zugegriffen werden, |
|||
als Gast nur lesend auf die Vorlage.</p> |
|||
<p>Statistische Daten zu dem Testfaellen: <br/> |
|||
- Anzahl in Projekten und Anwendungen <br/> |
|||
- letzte Durchfuehrungen (log) <br/> |
|||
- letzte Aenderungen (git log) <br/> |
|||
- info zu Begriff Testfall -> ucarmesin.de/joomla <br/> |
|||
- Suchfeld fuer speziellen Testfall -> Anzeige des Testfalls </p> |
|||
<button type="button" class="collapsible" data-toggle="collapse">Block Head/Option</button> |
|||
<div class="content collapsed" id="collapseOptions"> |
|||
<p>Diese Attribute ordnen den Testfall in einen Kontext ein und setzen Bearbeitungsparameter fuer die Durchfuehrung.</p> |
|||
</div> |
|||
<button type="button" class="collapsible" data-toggle="collapse">Block Steps</button> |
|||
<div class="content collapsed" id="collapseSteps"> |
|||
<p>Diese Attribute beschreiben die Schritte, die waehrend der Durchfuehrungsphase ausgefuehrt werden. |
|||
Die benoetigten Testdaten werden aus den Tabellen referenziert.</p> |
|||
</div> |
|||
<button type="collapscontent" class="collapsible" data-toggle="collapse">Block Tabellen</button> |
|||
<div class="content collapsed" id="collapseTables"> |
|||
<p>In den Tabellen sind die Testdaten hinterlegt, die waehrend der Initialisierungsphase vorbefuellt werden |
|||
oder waehrend der Durchfuehrungsphase eingespielt werden.</p> |
|||
</div> |
|||
|
|||
{% endblock %} |
@ -0,0 +1,9 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block header %} |
|||
<h1>{% block title %}Overview{% endblock %}</h1> |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<p>Hier kommt Inhalt rein</p> |
|||
{% endblock %} |
@ -0,0 +1,41 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
import utils.config_tool |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('testcase', __name__, url_prefix='/testcase') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
""" |
|||
it shows an overview to testcase |
|||
:param: nothing |
|||
:return: rendered page with jsondata |
|||
* info with link to ucarmesin.de/joomla |
|||
* last git-updates (specifications) |
|||
* last executions (-> reports) with status running|to-check|with-faults|ok |
|||
* selection of conrete testcase by application, testsuite, project, regex?, full name |
|||
""" |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testcase/overview.html') |
|||
|
@ -0,0 +1,31 @@ |
|||
# https://flask.palletsprojects.com/en/2.0.x/tutorial/views/ |
|||
# -------------------------------------------------------------- |
|||
import functools |
|||
|
|||
from flask import ( |
|||
Blueprint, flash, g, redirect, render_template, request, session, url_for |
|||
) |
|||
from werkzeug.security import check_password_hash, generate_password_hash |
|||
|
|||
from webflask.db import get_db |
|||
|
|||
bp = Blueprint('testsuite', __name__, url_prefix='/testsuite') |
|||
|
|||
@bp.route('/selection', methods=('GET', 'POST')) |
|||
def selection(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testsuite/selection.html') |
|||
|
|||
@bp.route('/overview', methods=('GET', 'POST')) |
|||
def overview(): |
|||
if request.method == 'POST': |
|||
error = None |
|||
|
|||
flash(error) |
|||
|
|||
return render_template('testsuite/overview.html') |
|||
|
Loading…
Reference in new issue