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