def test_empty_kvitable_with_labels_render_text(): kvit = KVITable({'foo':[], 'dog':[]}) show = kvit.render(as_format='ascii') assert '\n'.join([ '| foo | dog | Value |', '+-----+-----+-------+', ]) == show
def test_pretty_table_printer(): # Functional equivalence to # https://pypi.org/project/pretty-table-printer # https://github.com/cfmeyers/pretty_table_printer # (tests/test_pretty_table_printer.py # test_it_knows_how_to_print_itself) # # delta: # * KVITable doesn't have explicit field widths/truncation (implicit in pretty_table_printer?) # * KVITable default alignment is right instead of left # * KVITable doesn't show a bottom border kvit = KVITable(valuecol_name='name') kvit.add('Sam', id=1) kvit.add('Layla', id=2) kvit.add('Jack Gabriel', id=3) rows = kvit.get_rows() assert [ [ 1, 'Sam' ], [ 2, 'Layla' ], [ 3, 'Jack Gabriel' ], ] == rows show = kvit.render() assert '\n'.join([ '| id | name |', '+----+--------------+', '| 1 | Sam |', '| 2 | Layla |', '| 3 | Jack Gabriel |', ]) == show
def test_empty_kvitable_get(): kvit = KVITable() with pytest.raises(IndexError) as idxerr: foo = kvit.get(('foo', 'bar'), moo="cow") assert 'foo' in str(idxerr.value) assert 'bar' in str(idxerr.value) assert 'moo' in str(idxerr.value) assert 'cow' in str(idxerr.value)
def test_empty_kvitable_render_text(): kvit = KVITable() show = kvit.render(as_format='ascii') assert '\n'.join([ '| Value |', '+-------+', '| |', ]) == show
def test_kvitable_initial_kv_dict(): kvit = KVITable({'moo':['cow'], 'foo':['bar', 'baz']}) kvit.add("hi", ('moo', "cow"), foo='bar') kvit.add("howdy", ('moo', "cow"), foo='baz') hello = kvit.get(('foo', 'bar'), moo="cow") assert hello == "hi" hello2 = kvit.get(moo="cow", foo='baz') assert hello2 == "howdy"
def test_non_leaf_kvitable_add_uses_default_key_val(): kvit = KVITable() kvit.add("hi", ('moo', "cow"), foo='bar') kvit.add("oops", ('moo', "dog")) rows = kvit.get_rows() assert [ ['cow', 'bar', 'hi'], ['dog', '', 'oops'], ] == rows
def test_zoo_no_subtype_colstack_render(zoo_table): kv = zoo_table.keyvals() subtype_idx = list(kv.keys()).index('Subtype') del kv['Subtype'] zt2 = KVITable(kv, valuecol_name='Count', default_factory=int, kv_frozen=False) for row in zoo_table.get_rows(): del row[subtype_idx] zt2.add(lambda v: v + row[-1], *tuple(zip(kv, row[:-1]))) show = zt2.render(row_repeat=False, sort_vals=True, row_group=['Location', 'Biome', 'Category'], colstack_at='Name') assert '\n'.join([ '| Location | Biome | Category | Diet | Bear | Giraffe | Hippo | Lion | Penguin | Rhino | <- Name', '+-----------+----------+----------+-----------+------+---------+-------+------+---------+-------+', '| LA | Jungle | Animal | Herbivore | | | 1 | | | |', '| +----------+----------+-----------+------+---------+-------+------+---------+-------+', '| | Savannah | Animal | Carnivore | | | | 4 | | |', '| | | | Herbivore | | 2 | | | | 3 |', '+-----------+----------+----------+-----------+------+---------+-------+------+---------+-------+', '| Miami | Polar | Bird | Carnivore | | | | | 20 | |', '| +----------+----------+-----------+------+---------+-------+------+---------+-------+', '| | Savannah | Animal | Carnivore | | | | 2 | | |', '| | | | Herbivore | | 3 | | | | |', '+-----------+----------+----------+-----------+------+---------+-------+------+---------+-------+', '| New York | Savannah | Animal | Carnivore | | | | 3 | | |', '+-----------+----------+----------+-----------+------+---------+-------+------+---------+-------+', '| San Diego | Jungle | Animal | Omnivore | 1 | | | | | |', '| +----------+----------+-----------+------+---------+-------+------+---------+-------+', '| | Plains | Animal | Omnivore | 2 | | | | | |', '| +----------+----------+-----------+------+---------+-------+------+---------+-------+', '| | Polar | Animal | Omnivore | 1 | | | | | |', '| | +----------+-----------+------+---------+-------+------+---------+-------+', '| | | Bird | Carnivore | | | | | 10 | |', '| +----------+----------+-----------+------+---------+-------+------+---------+-------+', '| | Savannah | Animal | Carnivore | | | | 9 | | |', '+-----------+----------+----------+-----------+------+---------+-------+------+---------+-------+', ]) == show
def test_non_frozen_kvitable_add_key(): kvit = KVITable({'foo':['bar','baz']}, kv_frozen=False) kvit.add("hi", foo='bar') kvit.add("yo", foo='baz', dog='woof') rows = kvit.get_rows() assert [ [ 'bar', '', 'hi' ], [ 'baz', 'woof', 'yo'], ] == rows show = kvit.render() assert '\n'.join([ '| foo | dog | Value |', '+-----+------+-------+', '| bar | | hi |', '| baz | woof | yo |', ]) == show
def test_non_frozen_kvitable_add_deep_key(): kvit = KVITable({'foo':['bar','baz'], 'moon':['beam', 'pie'], }, kv_frozen=False, valuecol_name='says', keyval_factory=lambda key: '?') kvit.add("hi", foo='bar', moon='pie') kvit.add("yo", foo='baz', moon='beam', dog='woof') kvit.add("Excellent!", foo='Bill', moon='Ted', dog='arf arf') rows = kvit.get_rows() assert [ [ 'Bill', 'Ted', 'arf arf', 'Excellent!'], [ 'bar', 'pie', '?', 'hi' ], [ 'baz', 'beam', 'woof', 'yo'], ] == rows show = kvit.render(sort_vals=True) assert '\n'.join([ '| foo | moon | dog | says |', '+------+------+---------+------------+', '| Bill | Ted | arf arf | Excellent! |', '| bar | pie | ? | hi |', '| baz | beam | woof | yo |', ]) == show
def test_table_printer(): # Functional equivalence to https://pypi.org/project/table_printer # delta: # * KVITable does not support left/right/center alignment # * KVITable does not support explicit field widths kvit = KVITable(valuecol_name='Description') kvit.add('World', Title='Hello') kvit.add('1 title', Title='TOTAL') show = kvit.render(row_group=['Title']) assert '\n'.join([ '| Title | Description |', '+-------+-------------+', '| Hello | World |', '+-------+-------------+', '| TOTAL | 1 title |', '+-------+-------------+', ]) == show
def build_kvitable(): kvit = KVITable({'system': [ 'x86_64-linux', 'x86_64-darwin' ], 'Branch': ['master', 'develop', 'PR-feature'], 'Strategy': ['submodules', 'HEADs'], 'ghcver': ['ghc844', 'ghc865', 'ghc882'], }, kv_frozen=True) kvit.add('+', system='x86_64-linux', Strategy='submodules', ghcver='ghc844', Branch='PR-feature') kvit.add('FAIL*1', system='x86_64-linux', Strategy='HEADs', ghcver='ghc865', Branch='PR-feature') kvit.add('FAIL*1', system='x86_64-linux', Strategy='submodules', ghcver='ghc882', Branch='develop') kvit.add('+', system='x86_64-linux', Strategy='HEADs', ghcver='ghc865', Branch='develop') kvit.add('FAIL*1', system='x86_64-linux', Strategy='submodules', ghcver='ghc844', Branch='master') kvit.add('FAIL*1', system='x86_64-linux', Strategy='HEADs', ghcver='ghc844', Branch='master') kvit.add('FAIL*1', system='x86_64-linux', Strategy='HEADs', ghcver='ghc865', Branch='master') kvit.add('FAIL*1', system='x86_64-linux', Strategy='HEADs', ghcver='ghc882', Branch='master') kvit.add('FAIL*1', system='x86_64-linux', Strategy='submodules', ghcver='ghc865', Branch='master') kvit.add('+', system='x86_64-linux', Strategy='HEADs', ghcver='ghc844', Branch='develop') kvit.add('FAIL*1', system='x86_64-linux', Strategy='HEADs', ghcver='ghc882', Branch='PR-feature') kvit.add('FAIL*1', system='x86_64-linux', Strategy='submodules', ghcver='ghc882', Branch='PR-feature') kvit.add('+', system='x86_64-linux', Strategy='submodules', ghcver='ghc865', Branch='PR-feature') kvit.add('+', system='x86_64-linux', Strategy='submodules', ghcver='ghc844', Branch='develop') kvit.add('+', system='x86_64-linux', Strategy='HEADs', ghcver='ghc844', Branch='develop') kvit.add('+', system='x86_64-darwin', Strategy='HEADs', ghcver='ghc844', Branch='develop') return kvit
def test_kvitable_cannot_extend_leaf(): kvit = KVITable() kvit.add("hi", ('moo', "cow"), foo='bar') with pytest.raises(IndexError) as idxerr: kvit.add("woof", ('moo', "cow"), foo='bar', dog='bark') assert 'overwrite leaf' in str(idxerr.value)
def test_frozen_kvitable_add_key_key_refused(): kvit = KVITable({'foo':['bar','baz']}, kv_frozen=True) kvit.add("hi", foo='bar') with pytest.raises(IndexError) as idxerr: kvit.add("oops", ('dog', "bark"), foo='baz') assert 'kv_frozen' in str(idxerr.value)
def test_kvitable_initial_kv_list(): kvit = KVITable(['moo', 'foo']) kvit.add("hi", ('moo', "cow"), foo='bar') hello = kvit.get(('foo', 'bar'), moo="cow") assert hello == "hi"
def zoo_table(): kvit = KVITable({'Location': ['San Diego', 'LA', 'Miami', 'New York'], 'Biome': ['Savannah', 'Jungle', 'Polar'], 'Category': ['Animal', 'Reptile', 'Bird'], 'Diet': ['Herbivore', 'Carnivore'], 'Name': [], }, valuecol_name='Count', default_factory=int, kv_frozen=False) inc = lambda v: v+1 kvit.add(3, ('Diet', 'Carnivore'), ('Category', "Animal"), ('Biome', "Savannah"), Name='Lion', Location='New York') kvit.add(2, ('Diet', 'Carnivore'), ('Category', "Animal"), ('Biome', "Savannah"), Name='Lion', Location='Miami') kvit.add(4, ('Diet', 'Carnivore'), ('Category', "Animal"), ('Biome', "Savannah"), Name='Lion', Location='LA') kvit.add(8, ('Diet', 'Carnivore'), ('Category', "Animal"), ('Biome', "Savannah"), Name='Lion', Location='San Diego') kvit.add(2, Location='LA', Biome='Savannah', Category='Animal', Name='Giraffe', Diet='Herbivore') kvit.add(1, Location='LA', Biome='Jungle', Category='Animal', Name='Hippo', Diet='Herbivore') kvit.add(3, Location='LA', Biome='Savannah', Category='Animal', Diet='Herbivore', Name='Rhino') kvit.add(20, Location='Miami', Biome='Polar', Category='Bird', Diet='Carnivore', Subtype='Gentoo', Name='Penguin') kvit.add(8, Location='San Diego', Biome='Polar', Category='Bird', Diet='Carnivore', Subtype='Emperor', Name='Penguin') kvit.add(2, Location='San Diego', Biome='Polar', Category='Bird', Diet='Carnivore', Subtype='Gentoo', Name='Penguin') kvit.add(3, Location='Miami', Biome='Savannah', Category='Animal', Diet='Herbivore', Name='Giraffe', Subtype='Reticulated') kvit.add(inc, Category='Animal', Diet='Carnivore', Biome="Savannah", Location='San Diego', Name='Lion') kvit.add(inc, Location='San Diego', Biome='Polar', Category='Animal', Subtype='Polar', Name='Bear', Diet='Omnivore') kvit.add(inc, Location='San Diego', Biome='Jungle', Category='Animal', Subtype='Sun', Name='Bear', Diet='Omnivore') kvit.add(inc, Location='San Diego', Biome='Plains', Category='Animal', Subtype='Brown', Name='Bear', Diet='Omnivore') kvit.add(inc, Location='San Diego', Biome='Plains', Category='Animal', Subtype='Black', Name='Bear', Diet='Omnivore') return kvit
def test_ptable(): # Functional equivalence to https://pypi.org/project/PTable # # delta: # * KVITable default alignment is right instead of left kvit = KVITable(valuecol_name='Annual Rainfall') kvit.add(600.5, ('City name', 'Adelaide'), Area=1295, Population=1158259) kvit.add(1146.4, ('City name', 'Brisbane'), Area=5905, Population=1857594) kvit.add(1714.7, ('City name', 'Darwin'), Area=112, Population=120900) kvit.add(619.5, ('City name', 'Hobart'), Area=1357, Population=205556) kvit.add(646.9, ('City name', 'Melbourne'), Area=1566, Population=3806092) kvit.add(869.4, ('City name', 'Perth'), Area=5386, Population=1554769) kvit.add(1214.8, ('City name', 'Sydney'), Area=2058, Population=4336374) show = kvit.render() print(show) assert '\n'.join([ '| City name | Area | Population | Annual Rainfall |', '+-----------+------+------------+-----------------+', '| Adelaide | 1295 | 1158259 | 600.5 |', '| Brisbane | 5905 | 1857594 | 1146.4 |', '| Darwin | 112 | 120900 | 1714.7 |', '| Hobart | 1357 | 205556 | 619.5 |', '| Melbourne | 1566 | 3806092 | 646.9 |', '| Perth | 5386 | 1554769 | 869.4 |', '| Sydney | 2058 | 4336374 | 1214.8 |', ]) == show
def test_frozen_kvitable_initial_kv_list_refuses_new_values(): kvit = KVITable(['moo', 'foo'], kv_frozen=True) with pytest.raises(IndexError) as idxerr: kvit.add("hi", ('moo', "cow"), foo='bar') assert 'frozen' in str(idxerr.value)
def medium_kvitable(): kvit = KVITable({'compiler': [ 'gcc7', 'gcc8', 'clang6', 'clang7' ], 'debug': ['yes', 'no'], 'optimization': [0, 1, 3], }, kv_frozen=True) kvit.add('good', compiler='gcc7', debug='yes', optimization=0) kvit.add('bad', compiler='gcc7', debug='no', optimization=0) kvit.add('ugly', compiler='gcc7', debug='yes', optimization=3) kvit.add('good', compiler='gcc8', debug='yes', optimization=0) kvit.add('ok', compiler='clang6', debug='yes', optimization=0) kvit.add('good', compiler='clang7', debug='no', optimization=1) kvit.add('good', compiler='clang7', debug='no', optimization=3) kvit.add('good', compiler='clang7', debug='yes', optimization=3) kvit.add(True, compiler='gcc8', debug='yes', optimization=3) kvit.add('bad', compiler='gcc8', debug='yes', optimization=1) kvit.add('good', compiler='clang7', debug='no', optimization=0) kvit.add('good', compiler='gcc7', debug='no', optimization=1) return kvit
def test_empty_frozen_kvitable_add_refused(): kvit = KVITable(kv_frozen=True) with pytest.raises(IndexError) as idxerr: kvit.add("hi", ('moo', "cow"), foo='bar') assert "frozen" in str(idxerr.value)
def html_summary(repdata, base_builder_url=None): section_hdrfun = lambda msg: '<br/><hr class="section_line"/><br/><h2>' + msg + '</h2><br/>' subsection_hdrfun = lambda msg: '<br/><h3>' + msg + '</h3>' entshow_fun = tcell_entshow(base_builder_url) projects = set( [sr.project for sr in repdata if isinstance(sr, StatusReport)]) summary = KVITable(default_factory=int, valuecol_name='Total') summary.add(len(projects), Element='Projects') summary.add(len( set([ sr.branch for sr in repdata if isinstance(sr, StatusReport) and sr.branchtype == 'pullreq' ])), Element='Pull Requests') projtable = KVITable( { 'Project': sorted( list( set([ sr.project for sr in repdata if isinstance(sr, StatusReport) ]))), 'Status': ['TOTAL', 'ok', 'FAIL', 'pending'], }, valuecol_name='Number', kv_frozen=False, default_factory=int) fulltable = KVITable( { 'Branch': [], 'system': ['x86-64_linux'], 'Strategy': ['regular', 'submodules', 'HEADs'], 'Project': [], }, valuecol_name='Build Status', default_factory=lambda: None, keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else 'n/a', kv_frozen=False) mkDetailTable = lambda: KVITable( { 'system': ['x86-64_linux'], 'Branch': [], 'Strategy': ['regular', 'submodules', 'HEADs'], }, valuecol_name='Build Status', default_factory=lambda: None, keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else '', kv_frozen=False) detailtables = defaultdict(mkDetailTable) projtable_sts = lambda s: { 'initial_success': 'ok', 'succeeded': 'ok', # 'pending': 'pending', }.get(s, 'FAIL') for sr in repdata: if isinstance(sr, Notify): summary.add(_inc, Element='Notifications') elif isinstance(sr, PendingStatus): prev = [ r for r in repdata if isinstance(r, StatusReport) and r.project == sr.project and r.buildname == sr.buildname ] if not prev: summary.add(_inc, Element='Builds') projtable.add(_inc, Project=sr.project, Status="TOTAL") else: projtable.add(_dec, Project=sr.project, Status=projtable_sts(prev[0].status)) projtable.add(_inc, Project=sr.project, Status="pending") vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars]) fulltable.add(TCell_PendingBld(sr.project, sr.buildname), *vars, Project=sr.project, Branch=tbl_branch(sr), Strategy=sr.strategy) detailtables[sr.project].add(TCell_PendingBld( sr.project, sr.buildname), *vars, Branch=tbl_branch(sr), Strategy=sr.strategy) elif isinstance(sr, NewPending): summary.add(_inc, Element='Builds') projectname = sr.bldcfg.projectname buildname = buildcfg_name(sr.bldcfg) tbl_brname = tbl_branch_(buildname, sr.bldcfg.branchname) projtable.add(_inc, Project=projectname, Status="TOTAL") projtable.add(_inc, Project=projectname, Status="pending") vars = tuple([(v.varname, v.varvalue) for v in sr.bldcfg.bldvars]) fulltable.add(TCell_PendingBld(projectname, buildname), *vars, Project=projectname, Branch=tbl_brname, Strategy=sr.bldcfg.strategy) detailtables[sr.bldcfg.projectname].add( TCell_PendingBld(projectname, buildname), *vars, Branch=tbl_brname, Strategy=sr.bldcfg.strategy) elif isinstance(sr, StatusReport): summary.add(_inc, Element='Builds') projtable.add(_inc, Project=sr.project, Status=projtable_sts(sr.status)) projtable.add(_inc, Project=sr.project, Status='TOTAL') bldres = { 'initial_success': TCell_GoodBld, 'succeeded': TCell_GoodBld, 'fixed': TCell_GoodBld, 'bad_config': TCell_BadCfgBld, }.get(sr.status, lambda proj, name: TCell_FailBld(proj, name, sr.status))( sr.project, sr.buildname) fulltable.add(bldres, *tuple([(v.varname, v.varvalue) for v in sr.bldvars]), Project=sr.project, Branch=tbl_branch(sr), Strategy=sr.strategy) detailtables[sr.project].add(bldres, *tuple([(v.varname, v.varvalue) for v in sr.bldvars]), Branch=tbl_branch(sr), Strategy=sr.strategy) return '\n\n'.join([ summary.render(as_format='html', sort_vals=True), section_hdrfun('Per-project Build Status Summary ::'), projtable.render(row_group=['Project'], row_repeat=False, sort_vals=False, as_format='html', caption='Per-project Build Status Summary', colstack_at='Status'), section_hdrfun('Combined Details ::'), fulltable.render( row_group=['system', 'Branch', 'Strategy'], row_repeat=False, sort_vals=True, entrystr=entshow_fun, as_format='html', caption='Combined Details', colstack_at=(list(fulltable.keyvals().keys()) + [None])[4], ), section_hdrfun('Individual Project Summaries ::'), '\n\n'.join([ subsection_hdrfun('Project %s:\n' % p) + detailtables[p].render( row_repeat=False, as_format='html', caption='Project %s' % p, sort_vals=True, colstack_at=(list(detailtables[p].keyvals().keys()) + [None])[3], row_group=['system', 'Branch'], entrystr=entshow_fun, ) for p in sorted(projects) ]) ])
def test_empty_kvitable_add(): kvit = KVITable() kvit.add("hi", ('moo', "cow"), foo='bar') hello = kvit.get(('foo', 'bar'), moo="cow") assert hello == "hi"
def test_empty_kvitable_render_html(): kvit = KVITable() show = kvit.render(as_format='html') assert 'Value' in show
def test_empty_kvitable_create(): kvit = KVITable()
def test_empty_kvitable_with_labels_render_html(): kvit = KVITable({'foo':[], 'dog':[]}) show = kvit.render(as_format='html') assert 'Value' in show
def text_summary(repdata): sepline = '=' * 60 hashline = '#' * 60 banner = '\n\n%(sepline)s\n%(hashline)s\n%(sepline)s\n\n' % locals() section_hdrfun = lambda msg: banner + msg subsection_hdrfun = lambda msg: msg + '\n' entshow_fun = _show_with_fail projects = set( [sr.project for sr in repdata if isinstance(sr, StatusReport)]) summary = KVITable(default_factory=int, valuecol_name='Total') summary.add(len(projects), Element='Projects') summary.add(len( set([ sr.branch for sr in repdata if isinstance(sr, StatusReport) and sr.branchtype == 'pullreq' ])), Element='Pull Requests') projtable = KVITable( { 'Project': sorted( list( set([ sr.project for sr in repdata if isinstance(sr, StatusReport) ]))), 'Status': ['TOTAL', 'ok', 'FAIL', 'pending'], }, valuecol_name='Number', kv_frozen=False, default_factory=int) fulltable = KVITable( { 'Branch': [], 'system': ['x86-64_linux'], 'Strategy': ['regular', 'submodules', 'HEADs'], 'Project': [], }, valuecol_name='Build Status', default_factory=FailCount, keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else 'n/a', kv_frozen=False) mkDetailTable = lambda: KVITable( { 'system': ['x86-64_linux'], 'Branch': [], 'Strategy': ['regular', 'submodules', 'HEADs'], }, valuecol_name='Build Status', default_factory=FailCount, keyval_factory=lambda key: 'x86_64-linux' if key == 'system' else '', kv_frozen=False) detailtables = defaultdict(mkDetailTable) projtable_sts = lambda s: { 'initial_success': 'ok', 'succeeded': 'ok', # 'pending': 'pending', }.get(s, 'FAIL') for sr in repdata: if isinstance(sr, Notify): summary.add(_inc, Element='Notifications') elif isinstance(sr, PendingStatus): prev = [ r for r in repdata if isinstance(r, StatusReport) and r.project == sr.project and r.buildname == sr.buildname ] if not prev: summary.add(_inc, Element='Builds') projtable.add(_inc, Project=sr.project, Status="TOTAL") else: projtable.add(_dec, Project=sr.project, Status=projtable_sts(prev[0].status)) projtable.add(_inc, Project=sr.project, Status="pending") vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars]) fulltable.add(PendingBld, *vars, Project=sr.project, Branch=tbl_branch(sr), Strategy=sr.strategy) detailtables[sr.project].add(PendingBld, *vars, Branch=tbl_branch(sr), Strategy=sr.strategy) elif isinstance(sr, NewPending): summary.add(_inc, Element='Builds') projtable.add(_inc, Project=sr.bldcfg.projectname, Status="TOTAL") projtable.add(_inc, Project=sr.bldcfg.projectname, Status="pending") vars = tuple([(v.varname, v.varvalue) for v in sr.bldcfg.bldvars]) buildname = buildcfg_name(sr.bldcfg) tbl_brname = tbl_branch_(buildname, sr.bldcfg.branchname) fulltable.add(PendingBld, *vars, Project=sr.bldcfg.projectname, Branch=tbl_brname, Strategy=sr.bldcfg.strategy) detailtables[sr.bldcfg.projectname].add( PendingBld, *vars, Branch=tbl_brname, Strategy=sr.bldcfg.strategy) elif isinstance(sr, StatusReport): summary.add(_inc, Element='Builds') projtable.add(_inc, Project=sr.project, Status=projtable_sts(sr.status)) projtable.add(_inc, Project=sr.project, Status='TOTAL') bldres = _add_if_int({ 'initial_success': '+', 'succeeded': '+', 'fixed': '+', 'bad_config': '-CFG', }.get(sr.status, sr.status)) vars = tuple([(v.varname, v.varvalue) for v in sr.bldvars]) fulltable.add(bldres, *vars, Project=sr.project, Branch=tbl_branch(sr), Strategy=sr.strategy) detailtables[sr.project].add(bldres, *vars, Branch=tbl_branch(sr), Strategy=sr.strategy) keytable = KVITable({'Symbol': []}, valuecol_name='Meaning', kv_frozen=False) keytable.add('Success', Symbol='+') keytable.add("'n' build components failed", Symbol='FAIL*n') keytable.add('Build configuration error', Symbol='-CFG') keytable.add('Pending, no previous builds', Symbol='??') keytable.add('Pending, previously suceeding', Symbol='(+)?') keytable.add('Pending, previous config error', Symbol='(-CFG)?') keytable.add("Pending, previously 'n' components failed", Symbol='(-n)?') return '\n\n'.join([ summary.render( as_format='ascii', sort_vals=True, ), section_hdrfun('Per-project Build Status Summary ::'), projtable.render(row_group=['Project'], row_repeat=False, sort_vals=False, as_format='ascii', colstack_at='Status'), section_hdrfun('Combined Details ::'), fulltable.render( row_group=['system', 'Branch', 'Strategy'], row_repeat=False, sort_vals=True, entrystr=entshow_fun, as_format='ascii', colstack_at=(list(fulltable.keyvals().keys()) + [None])[4], ), section_hdrfun('Individual Project Summaries ::'), '\n\n'.join([ subsection_hdrfun('Project %s:\n' % p) + detailtables[p].render( row_repeat=False, sort_vals=True, as_format='ascii', colstack_at=(list(detailtables[p].keyvals().keys()) + [None])[3], row_group=['system', 'Branch'], entrystr=entshow_fun, ) for p in sorted(projects) ]), section_hdrfun('KEY ::'), keytable.render(as_format='ascii'), ])