cicd/unit_test_utils.js (108 lines of code) (raw):

function generate_udf_test(udf_name, test_cases) { const test_name = `${udf_name}_${uuidv4()}`; create_dataform_test_view(test_name, udf_name, test_cases); let expected_output_select_statements = []; let test_input_select_statements = []; test_cases.forEach((test_case) => { let udf_positional_inputs = []; test_case.inputs.forEach((input, index) => { udf_positional_inputs.push(`${input} AS test_input_${index}`); }); test_input_select_statements.push(`\n SELECT ${udf_positional_inputs.join(', ')}`); expected_output_select_statements.push(`SELECT ${test_case.expected_output} AS udf_output`); }); run_dataform_test( test_name, test_input_select_statements, expected_output_select_statements ); } function generate_udaf_test(udaf_name, test_case) { const test_name = `${udaf_name}_${uuidv4()}`; create_dataform_udaf_test_view(test_name, udaf_name, test_case); let expected_output_select_statements = []; let test_input_select_statements = []; let udf_positional_inputs = []; test_case.input_columns.forEach((input, index) => { if (!input.includes(' NOT AGGREGATE')) { udf_positional_inputs.push(`${input} AS test_input_${index}`); } }); test_input_select_statements.push(`\n SELECT ${udf_positional_inputs.join(', ')} FROM (${test_case.input_rows})`); expected_output_select_statements.push(`SELECT ${test_case.expected_output} AS udf_output`); run_dataform_test( test_name, test_input_select_statements, expected_output_select_statements ); } function create_dataform_test_view(test_name, udf_name, test_cases) { const inputs = Object.keys(test_cases[0].inputs); let udf_input_aliases = []; inputs.forEach((input, index) => { udf_input_aliases.push(`test_input_${index}`); }); udf_input_aliases = udf_input_aliases.join(','); const udf_invocation_str = `${get_udf_project_and_dataset(udf_name)}${udf_name}(${udf_input_aliases})`; publish(`${test_name}_dummy_view`).type("view").query("SELECT 1 as col1"); publish(test_name) .type("view") .query( (ctx) => `SELECT ${udf_invocation_str} AS udf_output\n` + `FROM ${ctx.resolve(`${test_name}_dummy_view`)}` ); } function create_dataform_udaf_test_view(test_name, udf_name, test_case) { let udf_input_aliases = []; test_case.input_columns.forEach((input, index) => { if (input.includes(' NOT AGGREGATE')) { udf_input_aliases.push(`${input.split(' NOT AGGREGATE')[0]}`); } else { udf_input_aliases.push(`test_input_${index}`); } }); udf_input_aliases = udf_input_aliases.join(','); const udf_invocation_str = `${get_udf_project_and_dataset(udf_name)}${udf_name}(${udf_input_aliases})`; publish(`${test_name}_dummy_view`).type("view").query("SELECT 1 as col1"); publish(test_name) .type("view") .query( (ctx) => `SELECT ${udf_invocation_str} AS udf_output\n` + `FROM ${ctx.resolve(`${test_name}_dummy_view`)}` ); } function run_dataform_test( test_name, test_input_select_statements, expected_output_select_statements ) { test(test_name) .dataset(test_name) .input( `${test_name}_dummy_view`, `${test_input_select_statements.join("\n UNION ALL")}` ) .expect(`${expected_output_select_statements.join("\nUNION ALL\n")}`); } function get_udf_project_and_dataset(udf_name) { // This function returns either a missing project_id or dataset_id // from the user-provided udf_name. Any missing IDs are added using data // from the dataform.json config file. const regexp = /\./g; // Check for periods in udf_name const matches = [...udf_name.matchAll(regexp)]; if (matches.length === 0) { // No periods in udf_name means project and dataset must be added // for a fully-qualified UDF invocation. return `\`${dataform.projectConfig.defaultDatabase}.${dataform.projectConfig.defaultSchema}\`.`; } else if (matches.length === 1) { // Only one period in udf_name means the project must be added // for a fully-qualified UDF invocation. return `\`${dataform.projectConfig.defaultDatabase}\`.`; } else if (matches.length === 2) { // Two periods in the udf_name means the user has already provided // both project and dataset. No change is necessary. return ''; } } // Source: https://stackoverflow.com/a/2117523 function uuidv4() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } module.exports = { generate_udf_test, generate_udaf_test, };