# -*- coding: utf-8 -*- """ Tests of Internal BoM files - Simple cases for: - CSV - HTML - XML - XLSX - Components units - Sort and groups of RLC_sort - Datasheet as link (HTML and XLSX) - Digi-Key link (HTML and XLSX) - Join columns - ignore_dnf = 0 - html_generate_dnf = 0 - use_alt = 1 (also non contiguous) - COLUMN_RENAME - CSV - HTML - XML - XLSX - group_connectors = 1/0 - Columns are case insensitive - component_aliases - merge_blank_fields - Don't group components - Multipart component (not repeated) - Field collision - test_regex/exclude_any/include_only - No XLSX support Missing: - number_boards - XLSX/HTML colors (for real) KiBoM Variants: - kibom-variant_2.sch - kibom-variant_5.sch IBoM Variants: - test_int_bom_variant_t2if + kibom-variant_3.sch + int_bom_var_t2i_csv - test_int_bom_variant_t2is + kibom-variant_3.sch + int_bom_var_t2is_csv - kibom-variant_4.sch For debug information use: pytest-3 --log-cli-level debug """ from base64 import b64decode import logging import os import pytest from . import context from kibot.misc import EXIT_BAD_CONFIG BOM_DIR = 'BoM' REF_COLUMN_NAME = 'References' REF_COLUMN_NAME_R = 'Referencias' QTY_COLUMN_NAME = 'Quantity Per PCB' STATUS_COLUMN_NAME = 'Status' COMP_COLUMN_NAME = 'Row' COMP_COLUMN_NAME_R = 'Renglón' VALUE_COLUMN_NAME = 'Value' DATASHEET_COLUMN_NAME = 'Datasheet' SOURCE_BOM_COLUMN_NAME = 'Source BoM' KIBOM_TEST_HEAD = [COMP_COLUMN_NAME, 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME, 'Status', DATASHEET_COLUMN_NAME, 'Config'] KIBOM_TEST_HEAD_TOL = list(KIBOM_TEST_HEAD) KIBOM_TEST_HEAD_TOL.insert(-1, 'Tolerance') KIBOM_RENAME_HEAD = [COMP_COLUMN_NAME_R, REF_COLUMN_NAME_R, 'Componente', 'Valor', 'Código Digi-Key', 'Cantidad por PCB'] CONN_HEAD = [COMP_COLUMN_NAME, 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME, 'Status', DATASHEET_COLUMN_NAME] KIBOM_TEST_COMPONENTS = ['C1', 'C2', 'C3', 'C4', 'R1', 'R2', 'R3', 'R4', 'R5', 'R7', 'R8', 'R9', 'R10'] KIBOM_TEST_COMPONENTS_FIL = ['C1', 'C2', 'C4', 'R1', 'R2', 'R3', 'R4', 'R5', 'R7', 'R8', 'R10'] KIBOM_TEST_COMPONENTS_FIL2 = ['C1', 'C2', 'R1', 'R2', 'R3', 'R4', 'R5', 'R7', 'R8', 'R10'] KIBOM_TEST_COMPONENTS_ALT = ['C1-C4', 'R9', 'R10', 'R7', 'R8', 'R1-R5'] KIBOM_TEST_COMPONENTS_ALT2 = ['C1-C4', 'R9', 'R10', 'R7', 'R8', 'R1', 'R2', 'R4', 'R5', 'R3'] KIBOM_TEST_EXCLUDE = ['R6'] KIBOM_TEST_GROUPS = 5 KIBOM_PRJ_INFO = ['kibom-test', 'default', 'A', '2020-03-12', None] LINKS_PRJ_INFO = ['links', 'default', 'A', '2020-03-12', None] KIBOM_STATS = [KIBOM_TEST_GROUPS+len(KIBOM_TEST_EXCLUDE), len(KIBOM_TEST_COMPONENTS)+len(KIBOM_TEST_EXCLUDE), len(KIBOM_TEST_COMPONENTS), 1, len(KIBOM_TEST_COMPONENTS)] LINKS_STATS = [3, '4 (2 SMD/ 2 THT)', '3 (1 SMD/ 2 THT)', 1, 3] VARIANTE_PRJ_INFO = ['kibom-variante', 'default', 'A', '2020-03-12', None] LINK_HEAD = ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'digikey_alt#', 'mouser#', 'mouser_alt#', 'LCSC#', 'manf#'] LINKS_COMPONENTS = ['J1', 'J2', 'R1'] LINKS_EXCLUDE = ['C1'] LINKS_GROUPS = 2 INFO_ROWS = ['Schematic:', 'Variant:', 'Revision:', 'Date:', 'KiCad Version:'] STATS_ROWS = ['Component Groups:', 'Component Count:', 'Fitted Components:', 'Number of PCBs:', 'Total Components:'] DEF_TITLE = 'KiBot Bill of Materials' MERGED_COMPS = ['A:R1-A:R3', 'A:C1', 'A:C2', 'B:R1', 'B:R2-B:R4', 'B:C1', 'B:C2', 'C:R1-C:R4', 'C:R5'] MERGED_R1_SRC = 'A:(3) B:(3) C:(1)' def check_kibom_test_netlist(rows, ref_column, groups, exclude, comps, ref_sep=' ', vals=None, val_column=None): """ Checks the kibom-test.sch expected results """ # Groups assert len(rows) == groups, "Number of groups" logging.debug(str(groups) + " groups OK") # Components if comps: components = [] comp_vals = {} for r in rows: components.extend(r[ref_column].split(ref_sep)) if val_column: comp_vals[r[ref_column]] = r[val_column] assert len(components) == len(comps), "Number of components" logging.debug(str(len(comps)) + " components OK") # Excluded if exclude: for ex in exclude: assert ex not in components logging.debug(str(len(exclude)) + " not fitted OK") # All the other components if comps: for c in comps: assert c in components logging.debug("list of components OK") # Check values if vals: for r, v in vals.items(): assert r in comp_vals assert v == comp_vals[r] logging.debug("component values OK") def check_dnc(rows, comp, ref, status, datasheet=None): for row in rows: if row[ref].find(comp) != -1: assert '(DNC)' in row[status] logging.debug(comp + " is DNC OK") if datasheet is not None: assert row[datasheet].startswith('= context.KICAD_VERSION_5_99: # V6 schematics are self-contained, no point in checking for libs return prj = 'v5_errors/kibom-test' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_simple_csv', BOM_DIR) ctx.run() out = 'kibom-test-bom.csv' rows, header, info = ctx.load_csv(out) check_csv_info(info, KIBOM_PRJ_INFO, KIBOM_STATS) kibom_verif(rows, header) ctx.search_err(r'Missing library (.*) \(t1') ctx.search_err(r'Missing doc-lib entry for t2:R') ctx.clean_up() def test_int_bom_variant_t1(test_dir): prj = 'kibom-variante' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t1_csv', BOM_DIR) ctx.run() # No variant logging.debug("* No variant") rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R4'], ['R1', 'R2', 'R3']) VARIANTE_PRJ_INFO[1] = 'default' check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 3, 1, 3]) # V1 logging.debug("* t1_v1 variant") rows, header, info = ctx.load_csv(prj+'-bom_(V1).csv') check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2']) ctx.search_err(r'Field Config of component (.*) contains extra spaces') VARIANTE_PRJ_INFO[1] = 't1_v1' check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 2, 1, 2]) # V2 logging.debug("* t1_v2 variant") rows, header, info = ctx.load_csv(prj+'-bom_(V2).csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R4'], ['R1', 'R3']) VARIANTE_PRJ_INFO[1] = 't1_v2' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) # V3 logging.debug("* t1_v3 variant") rows, header, info = ctx.load_csv(prj+'-bom_V3.csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4']) VARIANTE_PRJ_INFO[1] = 't1_v3' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) # V1,V3 logging.debug("* `bla bla` variant") rows, header, info = ctx.load_csv(prj+'-bom_bla_bla.csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4']) VARIANTE_PRJ_INFO[1] = 'bla bla' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) ctx.clean_up() def check_value(rows, r_col, ref, v_col, val): for r in rows: refs = r[r_col].split(' ') if ref in refs: assert r[v_col] == val logging.debug(ref+'='+val+' OK') return raise AssertionError("Failed to find "+ref) def test_int_bom_variant_t2b(test_dir): prj = 'kibom-variant_2' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) val_column = header.index(VALUE_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) check_value(rows, ref_column, 'R1', val_column, '1k') rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2']) check_value(rows, ref_column, 'R1', val_column, '1k') rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2']) check_value(rows, ref_column, 'R1', val_column, '3k3') ctx.clean_up() def test_int_bom_variant_t2c(test_dir): """ Test KiBoM variant and field rename filter, R1 must be changed to 3k3 """ prj = 'kibom-variant_2' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2c_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') ref_column = header.index(REF_COLUMN_NAME) val_column = header.index(VALUE_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2']) check_value(rows, ref_column, 'R1', val_column, '3k3') ctx.clean_up() def test_int_bom_variant_rename_1(test_dir): prj = 'f_rename_1' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_rename_1_csv', BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv(prj+'-bom_(PROD).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R2', 'D2'], ['R1', 'D1']) rows, header, info = ctx.load_csv(prj+'-bom_(DEV).csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R1', 'R2', 'D1', 'D2']) ctx.clean_up() def test_int_bom_variant_rename_2(test_dir): prj = 'f_rename_2' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_rename_2_csv', BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv(prj+'-bom_(PROD).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R2', 'D2'], ['R1', 'D1']) rows, header, info = ctx.load_csv(prj+'-bom_(DEV).csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R1', 'R2', 'D1', 'D2']) ctx.clean_up() def test_int_bom_variant_t2s(test_dir): prj = 'kibom-variant_2' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2s_csv', BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv(prj+'-bom_(dummy).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) rows, header, info = ctx.load_csv(prj+'-bom_(dummy2).csv') check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) ctx.clean_up() def test_int_bom_variant_t2if(test_dir): """ IBoM variants test full """ prj = 'kibom-variant_3' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2i_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['C1', 'C2'], ['R1', 'R2', 'R3']) rows, header, info = ctx.load_csv(prj+'-bom_[2].csv') check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') check_kibom_test_netlist(rows, ref_column, 3, ['C1'], ['R1', 'R2', 'C2', 'R3']) rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') check_kibom_test_netlist(rows, ref_column, 3, ['R2'], ['R1', 'C1', 'C2', 'R3']) ctx.clean_up(keep_project=True) @pytest.mark.skipif(context.ki5(), reason="needs KiCad 6 text variables") def test_int_bom_variant_t2it(test_dir): """ IBoM variants test full, here we expand KiCad 6 variables """ prj = 'kibom-variant_3_txt' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2i_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['C1', 'C2'], ['R1', 'R2', 'R3']) rows, header, info = ctx.load_csv(prj+'-bom_[2].csv') check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') check_kibom_test_netlist(rows, ref_column, 3, ['C1'], ['R1', 'R2', 'C2', 'R3']) rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') check_kibom_test_netlist(rows, ref_column, 3, ['R2'], ['R1', 'C1', 'C2', 'R3']) ctx.clean_up(keep_project=True) def test_int_bom_variant_t2is(test_dir): """ IBoM variants test simple """ prj = 'kibom-variant_3' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2is_csv', BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv('filter_R1.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R2', 'R1'], ['C1', 'C2', 'R3']) ctx.clean_up(keep_project=True) def test_int_bom_variant_t2kf(test_dir): """ KiCost variants test full. R1 must be changed to 3k3. We also test the DNP mechanism. """ prj = 'kibom-variant_kicost' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t2k_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2'], ['R1', 'R2']) rows, header, info = ctx.load_csv(prj+'-bom_(production).csv') check_kibom_test_netlist(rows, ref_column, 2, ['C1'], ['R1', 'R2', 'C2']) val_column = header.index(VALUE_COLUMN_NAME) check_value(rows, ref_column, 'R1', val_column, '1k') rows, header, info = ctx.load_csv(prj+'-bom_(test).csv') check_kibom_test_netlist(rows, ref_column, 2, ['R2'], ['R1', 'C1', 'C2']) check_value(rows, ref_column, 'R1', val_column, '3k3') ctx.clean_up() def test_int_bom_wrong_variant(test_dir): ctx = context.TestContextSCH(test_dir, 'links', 'int_bom_wrong_variant', '') ctx.run(EXIT_BAD_CONFIG) assert ctx.search_err("Unknown variant name") ctx.clean_up() def test_int_bom_fil_dummy(test_dir): prj = 'kibom-test-4' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_fil_dummy', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, ['R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'C1', 'C2']) ctx.search_err('Field conflict', invert=True) ctx.clean_up() def test_int_bom_fil_1(test_dir): prj = 'kibom-test-4' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_fil_1', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv('empty_val.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 3, None, ['R3', 'R4', 'R5', 'R6', 'C1', 'C2']) rows, header, info = ctx.load_csv('by_prefix.csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R2', 'R3', 'R4', 'R5', 'R6']) rows, header, info = ctx.load_csv('no_kk.csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R1', 'R2', 'R5', 'R6', 'C1', 'C2']) rows, header, info = ctx.load_csv('no_conf_kk.csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R1', 'R2', 'R3', 'R4', 'C1', 'C2']) rows, header, info = ctx.load_csv('no_by_prefix.csv') check_kibom_test_netlist(rows, ref_column, 2, None, ['R1', 'C1', 'C2']) rows, header, info = ctx.load_csv('multi.csv') check_kibom_test_netlist(rows, ref_column, 1, None, ['C1', 'C2']) ctx.search_err('Field conflict') ctx.clean_up() def test_int_bom_fil_2(test_dir): prj = 'kibom-variant_3' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_fil_2', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv('smd.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 3, None, ['R2', 'C2', 'FID1']) rows, header, info = ctx.load_csv('tht.csv') check_kibom_test_netlist(rows, ref_column, 3, None, ['R1', 'C1', 'FID1']) rows, header, info = ctx.load_csv('virtual.csv') check_kibom_test_netlist(rows, ref_column, 2, None, ['R1', 'R2', 'C1', 'C2']) ctx.search_err(r".?R3.? component in board, but not in schematic") ctx.test_compress(prj+'-result.zip', ['BoM/smd.csv', 'BoM/tht.csv', 'BoM/virtual.csv']) ctx.clean_up(keep_project=True) def test_int_bom_variant_t3(test_dir): """ Test if we can move the filters to the variant. Also test the '!' filter (always false) """ prj = 'kibom-variante' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t3_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom_(V1).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2']) VARIANTE_PRJ_INFO[1] = 't1_v1' check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 2, 1, 2]) ctx.search_err(r"Creating internal filter(.*)_mechanical") ctx.search_err(r"Creating internal filter(.*)_kibom_dnf_Config") ctx.search_err(r"Creating internal filter(.*)_kibom_dnc") rows, header, info = ctx.load_csv(prj+'-bom_(V1b).csv') # Here we remove the DNC, so R1 and R2 becomes identical check_kibom_test_netlist(rows, ref_column, 1, ['R3', 'R4'], ['R1', 'R2']) ctx.clean_up() def test_int_bom_variant_cli(test_dir): """ Assign t1_v1 to default from cli. Make sure t1_v3 isn't affected """ prj = 'kibom-variante' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t1_cli', BOM_DIR) ctx.run(extra=['--global-redef', 'variant=t1_v1']) # No variant -> t1_v1 logging.debug("* No variant -> t1_v1") rows, header, info = ctx.load_csv(prj+'-bom_(V1).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2']) VARIANTE_PRJ_INFO[1] = 't1_v1' check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 2, 1, 2]) # V3 logging.debug("* t1_v3 variant") rows, header, info = ctx.load_csv(prj+'-bom_V3.csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4']) VARIANTE_PRJ_INFO[1] = 't1_v3' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) ctx.clean_up() def test_int_bom_variant_glb(test_dir): """ Assign t1_v1 to default from global. Make sure t1_v3 isn't affected """ prj = 'kibom-variante' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t1_glb', BOM_DIR) ctx.run() # No variant -> t1_v1 logging.debug("* No variant -> t1_v1") rows, header, info = ctx.load_csv(prj+'-bom_(V1).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 2, ['R3', 'R4'], ['R1', 'R2']) VARIANTE_PRJ_INFO[1] = 't1_v1' check_csv_info(info, VARIANTE_PRJ_INFO, [4, 20, 2, 1, 2]) # V3 logging.debug("* t1_v3 variant") rows, header, info = ctx.load_csv(prj+'-bom_V3.csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4']) VARIANTE_PRJ_INFO[1] = 't1_v3' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) def test_int_bom_variant_cl_gl(test_dir): """ Assign t1_v1 to default from global. Overwrite it from cli to t1_v2. Make sure t1_v3 isn't affected """ prj = 'kibom-variante' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_t1_glb', BOM_DIR) ctx.run(extra=['--global-redef', 'variant=t1_v2']) ctx.search_out(r'Using command line value .?t1_v2.? for global option .?variant.?') # No variant -> t1_v2 logging.debug("* No variant -> t1_v2") rows, header, info = ctx.load_csv(prj+'-bom_(V2).csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R4'], ['R1', 'R3']) VARIANTE_PRJ_INFO[1] = 't1_v2' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) # V3 logging.debug("* t1_v3 variant") rows, header, info = ctx.load_csv(prj+'-bom_V3.csv') check_kibom_test_netlist(rows, ref_column, 1, ['R2', 'R3'], ['R1', 'R4']) VARIANTE_PRJ_INFO[1] = 't1_v3' check_csv_info(info, VARIANTE_PRJ_INFO, [3, 20, 2, 1, 2]) ctx.clean_up() def test_int_bom_ref_separator(test_dir): ctx, out = kibom_setup(test_dir, 'int_bom_ref_separator') rows, header, info = ctx.load_csv(out) check_csv_info(info, KIBOM_PRJ_INFO, KIBOM_STATS) kibom_verif(rows, header, ref_sep=',') ctx.clean_up() def test_int_bom_variant_5(test_dir): prj = 'kibom-variant_5' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_var_5_csv', BOM_DIR) ctx.run() rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 1, ['C1', 'C2', 'R1'], ['R2']) ctx.clean_up() def test_int_bom_merge_csv_1(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_csv_1' if context.ki6(): yaml += '_k6' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.search_err(r'Stats for') ctx.clean_up() def test_int_bom_merge_csv_2(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_csv_2' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run(extra_debug=True) rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.search_err(r'Stats for') ctx.clean_up() def test_int_bom_merge_html_1(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_html_1' if context.ki6(): yaml += '_k6' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header, info = ctx.load_html(prj+'-bom.html') logging.debug(rows[0]) ref_column = header[0].index(REF_COLUMN_NAME) check_kibom_test_netlist(rows[0], ref_column, 4, None, MERGED_COMPS) src_column = header[0].index(SOURCE_BOM_COLUMN_NAME) check_source(rows[0], 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_merge_html_2(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_html_2' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header, info = ctx.load_html(prj+'-bom.html') logging.debug(rows[0]) ref_column = header[0].index(REF_COLUMN_NAME) check_kibom_test_netlist(rows[0], ref_column, 4, None, MERGED_COMPS) src_column = header[0].index(SOURCE_BOM_COLUMN_NAME) check_source(rows[0], 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_merge_xlsx_1(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_xlsx_1' if context.ki6(): yaml += '_k6' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header, info = ctx.load_xlsx(prj+'-bom.xlsx') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_merge_xlsx_2(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_xlsx_2' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header, info = ctx.load_xlsx(prj+'-bom.xlsx') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_merge_xml_1(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_xml_1' if context.ki6(): yaml += '_k6' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header = ctx.load_xml(prj+'-bom.xml') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME.replace(' ', '_')) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_merge_xml_2(test_dir): prj = 'merge_1' yaml = 'int_bom_merge_xml_2' ctx = context.TestContextSCH(test_dir, prj, yaml, BOM_DIR) ctx.run() rows, header = ctx.load_xml(prj+'-bom.xml') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, MERGED_COMPS) src_column = header.index(SOURCE_BOM_COLUMN_NAME.replace(' ', '_')) check_source(rows, 'A:R1', ref_column, src_column, MERGED_R1_SRC) ctx.clean_up() def test_int_bom_subparts_1(test_dir): prj = 'subparts' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_subparts_1') ctx.run(extra_debug=True) output = prj+'-bom.csv' ctx.expect_out_file(output) ctx.compare_txt(output) ctx.clean_up() def test_int_bom_subparts_2(test_dir): prj = 'subparts_rename' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_subparts_2') ctx.run(extra_debug=True) output = prj+'-bom.csv' ctx.expect_out_file(output) ctx.compare_txt(output, 'subparts-bom.csv') ctx.clean_up() def test_int_bom_subparts_3(test_dir): prj = 'subparts_rename' ctx = context.TestContextSCH(test_dir, prj, 'int_bom_subparts_3') ctx.run(extra_debug=True) output = prj+'-bom.csv' ctx.expect_out_file(output) ctx.compare_txt(output, 'subparts-bom.csv') ctx.clean_up() @pytest.mark.skipif(not context.ki6(), reason="Target is v6+") def test_value_change_1(test_dir): prj = 'value_change' ctx = context.TestContextSCH(test_dir, 'shared_page_value_change/'+prj, 'value_change_1', 'Modified') ctx.run() sch = ctx.expect_out_file_d(prj+'.kicad_sch') ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'int_bom_csv_no_info', 'BoM') ctx.run(no_board_file=True, extra=['-e', sch]) rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 4, None, ['C1', 'C2', 'J1', 'J2', 'R1', 'R2'], vals={'C1': '150p', 'C2': '220p'}, val_column=header.index('Value')) ctx.clean_up() @pytest.mark.skipif(not context.ki6(), reason="Target is v6+") def test_value_change_2(test_dir): prj = 'value_change' ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'value_change_2', 'Modified') ctx.run() sch = ctx.expect_out_file_d(prj+'.kicad_sch') # assert False ctx = context.TestContextSCH(test_dir, 'shared_page_value_change_complex/'+prj, 'int_bom_csv_no_info', 'BoM') ctx.run(no_board_file=True, extra=['-e', sch]) rows, header, info = ctx.load_csv(prj+'-bom.csv') ref_column = header.index(REF_COLUMN_NAME) check_kibom_test_netlist(rows, ref_column, 5, None, ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'J1', 'J2', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6'], vals={'C1 C3 C6': '150p', 'C2 C4': '220p', 'C5': '330p'}, val_column=header.index('Value')) ctx.clean_up()