From 5058af50385020d2906ca5cb55a612fa57c90da8 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Fri, 31 Jul 2020 19:31:36 -0300 Subject: [PATCH] Added tests for XML and XLSX internal BoM --- tests/test_plot/test_int_bom.py | 46 ++++++++++++++++++- tests/utils/context.py | 45 ++++++++++++++++-- .../int_bom_simple_xlsx.kiplot.yaml | 12 +++++ .../int_bom_simple_xml.kiplot.yaml | 12 +++++ 4 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 tests/yaml_samples/int_bom_simple_xlsx.kiplot.yaml create mode 100644 tests/yaml_samples/int_bom_simple_xml.kiplot.yaml diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index fd183cce..21ecaae9 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -22,7 +22,7 @@ if prev_dir not in sys.path: # from kiplot.misc import (BOM_ERROR) BOM_DIR = 'BoM' -REF_COLUMN_NAME = 'Reference' +REF_COLUMN_NAME = 'Reference' # TODO make the same as KiBoM QTY_COLUMN_NAME = 'Quantity Per PCB' KIBOM_TEST_HEAD = ['Component', 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME, 'Datasheet', 'config'] @@ -32,7 +32,7 @@ KIBOM_TEST_GROUPS = 5 def check_kibom_test_netlist(rows, ref_column, groups, exclude, comps): - """ Checks the kibom-test.xml expected results """ + """ Checks the kibom-test.sch expected results """ # Groups assert len(rows) == groups logging.debug(str(groups) + " groups OK") @@ -102,3 +102,45 @@ def test_int_bom_simple_html(): # Check the DNF table check_kibom_test_netlist(rows[1], ref_column, 1, KIBOM_TEST_COMPONENTS, KIBOM_TEST_EXCLUDE) ctx.clean_up() + + +def adapt_xml(h): + h = h.replace(' ', '_') + h = h.replace('"', '') + h = h.replace("'", '') + h = h.replace('#', '_num') + return h + + +def test_int_bom_simple_xml(): + prj = 'kibom-test' + ext = 'xml' + ctx = context.TestContext('test_int_bom_simple_xml', prj, 'int_bom_simple_xml', BOM_DIR) + ctx.run(no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(), prj+'.sch')]) + out = prj + '-bom.' + ext + rows, header = ctx.load_xml(out) + # Columns get sorted by name, so we need to take care of it + for c in KIBOM_TEST_HEAD: + if c == 'Component': + continue + assert adapt_xml(c) in header, "Missing column "+c + ref_column = header.index(adapt_xml(REF_COLUMN_NAME)) + qty_column = header.index(adapt_xml(QTY_COLUMN_NAME)) + check_kibom_test_netlist(rows, ref_column, KIBOM_TEST_GROUPS, KIBOM_TEST_EXCLUDE, KIBOM_TEST_COMPONENTS) + check_dnc(rows, 'R7', ref_column, qty_column) + ctx.clean_up() + + +def test_int_bom_simple_xlsx(): + prj = 'kibom-test' + ext = 'xlsx' + ctx = context.TestContext('test_int_bom_simple_xlsx', prj, 'int_bom_simple_xlsx', BOM_DIR) + ctx.run(no_board_file=True, extra=['-e', os.path.join(ctx.get_board_dir(), prj+'.sch')]) + out = prj + '-bom.' + ext + rows, header = ctx.load_xlsx(out) + assert header == KIBOM_TEST_HEAD + ref_column = header.index(REF_COLUMN_NAME) + qty_column = header.index(QTY_COLUMN_NAME) + check_kibom_test_netlist(rows, ref_column, KIBOM_TEST_GROUPS, KIBOM_TEST_EXCLUDE, KIBOM_TEST_COMPONENTS) + check_dnc(rows, 'R7', ref_column, qty_column) + ctx.clean_up() diff --git a/tests/utils/context.py b/tests/utils/context.py index e17c103d..27638974 100644 --- a/tests/utils/context.py +++ b/tests/utils/context.py @@ -8,6 +8,7 @@ import pytest import csv from glob import glob from pty import openpty +import xml.etree.ElementTree as ET COVERAGE_SCRIPT = 'python3-coverage' KICAD_PCB_EXT = '.kicad_pcb' @@ -340,18 +341,18 @@ class TestContext(object): logging.debug("Found apertures {}".format(aps)) return aps - def load_csv(self, filename, column=3): + def load_csv(self, filename): rows = [] with open(self.expect_out_file(os.path.join(self.sub_dir, filename))) as csvfile: reader = csv.reader(csvfile) - header = next(reader) # Skip header + header = next(reader) for r in reader: if not r: break rows.append(r) return rows, header - def load_html(self, filename, column=4, split=True): + def load_html(self, filename): file = self.expect_out_file(os.path.join(self.sub_dir, filename)) with open(file) as f: html = f.read() @@ -375,6 +376,44 @@ class TestContext(object): c += 1 return rows, headers + def load_xml(self, filename): + rows = [] + headers = None + for child in ET.parse(self.expect_out_file(os.path.join(self.sub_dir, filename))).getroot(): + rows.append([v for v in child.attrib.values()]) + if not headers: + headers = [k for k in child.attrib.keys()] + return rows, headers + + def load_xlsx(self, filename): + """ Assumes the components are in sheet1 """ + file = self.expect_out_file(os.path.join(self.sub_dir, filename)) + subprocess.call(['unzip', file, '-d', self.get_out_path('desc')]) + # Some XMLs are stored with 0600 preventing them to be read by next CI/CD stage + subprocess.call(['chmod', '-R', 'og+r', self.get_out_path('desc')]) + # Read the table + worksheet = self.get_out_path(os.path.join('desc', 'xl', 'worksheets', 'sheet1.xml')) + rows = [] + root = ET.parse(worksheet).getroot() + ns = '{http://schemas.openxmlformats.org/spreadsheetml/2006/main}' + rnum = 1 + for r in root.iter(ns+'row'): + rcur = int(r.attrib['r']) + if rcur > rnum: + break + rows.append([int(cell.text) for cell in r.iter(ns+'v')]) + rnum += 1 + # Read the strings + strings = self.get_out_path(os.path.join('desc', 'xl', 'sharedStrings.xml')) + strs = [t.text for t in ET.parse(strings).getroot().iter(ns+'t')] + # Replace the indexes by the strings + for r in rows: + for i in range(len(r)): + r[i] = strs[r[i]] + # Separate the headers + headers = rows.pop(0) + return rows, headers + class TestContextSCH(TestContext): diff --git a/tests/yaml_samples/int_bom_simple_xlsx.kiplot.yaml b/tests/yaml_samples/int_bom_simple_xlsx.kiplot.yaml new file mode 100644 index 00000000..e650c88f --- /dev/null +++ b/tests/yaml_samples/int_bom_simple_xlsx.kiplot.yaml @@ -0,0 +1,12 @@ +# Example KiPlot config file +kiplot: + version: 1 + +outputs: + - name: 'bom_internal' + comment: "Bill of Materials in HTML format" + type: bom + dir: BoM + options: + format: XLSX + diff --git a/tests/yaml_samples/int_bom_simple_xml.kiplot.yaml b/tests/yaml_samples/int_bom_simple_xml.kiplot.yaml new file mode 100644 index 00000000..f801cc23 --- /dev/null +++ b/tests/yaml_samples/int_bom_simple_xml.kiplot.yaml @@ -0,0 +1,12 @@ +# Example KiPlot config file +kiplot: + version: 1 + +outputs: + - name: 'bom_internal' + comment: "Bill of Materials in HTML format" + type: bom + dir: BoM + options: + format: XML +