Skip to content

Commit

Permalink
added test multi-plexing
Browse files Browse the repository at this point in the history
  • Loading branch information
pyramation committed Jun 3, 2024
1 parent d0e13a7 commit 1efef64
Show file tree
Hide file tree
Showing 12 changed files with 1,670 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .yamlize/versions/14-latest.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
env:
JOB: pg-14
PGENV: pg-14
LIBPG_REPO: https://github.com/pganalyze/libpg_query.git
LIBPG_COMMIT: 1577ef7c6c349542149e34ffbfafc244ab942ec6
LIBPG_BRANCH: 14-latest
Expand Down
2 changes: 1 addition & 1 deletion .yamlize/versions/15-latest.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
env:
JOB: pg-15
PGENV: pg-15
LIBPG_REPO: https://github.com/pganalyze/libpg_query.git
LIBPG_COMMIT: db39825bc7c1ddd45962ec6a626d740b7f8f027a
LIBPG_BRANCH: 15-latest
Expand Down
2 changes: 1 addition & 1 deletion .yamlize/versions/16-latest.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
env:
JOB: pg-16
PGENV: pg-16
LIBPG_REPO: https://github.com/pganalyze/libpg_query.git
LIBPG_COMMIT: 1ec38940e5c6f09a4c1d17a46d839a881c4f2db7
LIBPG_BRANCH: 16-latest
Expand Down
15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"generate:workflows:no-win": "node script/generate-non-win-workflows.js",
"generate:workflows": "npm run generate:workflows:win && npm run generate:workflows:no-win",
"generate:build": "node script/utils/generate.js",
"test": "mocha --timeout 5000",
"test": "node run-tests.js",
"binary:build": "node-pre-gyp rebuild package",
"binary:publish": "AWS_PROFILE=supabase-dev node-pre-gyp publish"
},
Expand Down Expand Up @@ -83,5 +83,16 @@
"module_path": "./build/Release/",
"host": "https://supabase-public-artifacts-bucket.s3.amazonaws.com",
"remote_path": "./libpg-query-node/"
},
"libpgQueryConfig": {
"PGENV": "pg-15",
"LIBPG_REPO": "https://github.com/pganalyze/libpg_query.git",
"LIBPG_COMMIT": "db39825bc7c1ddd45962ec6a626d740b7f8f027a",
"LIBPG_BRANCH": "15-latest",
"PGSQL_TYPES": "15.0.2",
"OPERATING_SYSTEMS": [
"linux",
"mac"
]
}
}
}
26 changes: 26 additions & 0 deletions run-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');

const packagePath = path.join(__dirname, 'package.json');
const package = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
const pgEnv = package.libpgQueryConfig.PGENV;

// Construct the Mocha command
const testCommand = `mocha --timeout 5000 "test/${pgEnv}.test.js"`;

console.log(`Running tests: ${pgEnv}`);
console.log(`Executing: ${testCommand}`);

// Execute the Mocha command
exec(testCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(stdout);
});
11 changes: 0 additions & 11 deletions script/env.generated.json

This file was deleted.

18 changes: 7 additions & 11 deletions script/utils/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ const {
getTemplates
} = require('./get-templates');

// Read the JOB from the command line arguments
const jobFilter = process.argv[2];
console.log({jobFilter})
// Read the PGENV from the command line arguments
const envFilter = process.argv[2];
console.log({envFilter})

if (!jobFilter) {
if (!envFilter) {
console.error('Usage: node script.js <ENV>');
console.error('ENV is PG version, e.g. pg-15');
process.exit(1);
Expand All @@ -31,10 +31,10 @@ const templates = getTemplates(templatesDir);
const configs = getConfig(configDir);

// Filter configurations based on the command line input
const filteredConfigs = configs.filter(config => config.JOB === jobFilter);
const filteredConfigs = configs.filter(config => config.PGENV === envFilter);

if (filteredConfigs.length === 0) {
console.error(`No configurations found for ENV: ${jobFilter}`);
console.error(`No configurations found for ENV: ${envFilter}`);
process.exit(1);
}

Expand All @@ -52,6 +52,7 @@ const packageJsonPath = path.join(__dirname, '../../package.json');
let packageJson = fs.readFileSync(packageJsonPath, 'utf8');
packageJson = JSON.parse(packageJson);
packageJson.dependencies['@pgsql/types'] = config.PGSQL_TYPES;
packageJson.libpgQueryConfig = config;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');

// Generate build files from the templates
Expand All @@ -66,11 +67,6 @@ templates.forEach(template => {

// Define the output path for the processed template
const outputFile = path.join(outputDir, `${template.name}`);
const generatedEnv = path.join(outputDir, `env.generated.json`);

// Write the processed template to the output directory
fs.writeFileSync(generatedEnv, JSON.stringify(config, null, 2), 'utf8');


// Determine the file extension
const extension = path.extname(outputFile).toLowerCase();
Expand Down
File renamed without changes.
143 changes: 143 additions & 0 deletions test/pg-15.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
const query = require("../");
const { expect } = require("chai");
const { omit, cloneDeepWith } = require("lodash");

describe("Queries", () => {
describe("Sync Parsing", () => {
it("should return a single-item parse result for common queries", () => {
const queries = ["select 1", "select null", "select ''", "select a, b"];
const results = queries.map(query.parseQuerySync);
results.forEach((res) => {
expect(res.stmts).to.have.lengthOf(1);
});

// Do some rough asserting on the shape of the result.
// These tests aren't really meant to test the parsing functionality
// itself, but doing a bit for sanity doesn't hurt.
const selectedDatas = results.map(
(it) => it.stmts[0].stmt.SelectStmt.targetList
);

expect(selectedDatas[0][0].ResTarget.val.A_Const.ival.ival).to.eq(
1
);
expect(selectedDatas[1][0].ResTarget.val.A_Const.isnull).to.eq(
true
);
expect(selectedDatas[2][0].ResTarget.val.A_Const.sval.sval).to.eq(
""
);
expect(selectedDatas[3]).to.have.lengthOf(2);
});

it("should support parsing multiple queries", () => {
const res = query.parseQuerySync("select 1; select null;");
const changedProps = [
"stmt_len",
"stmt_location",
"stmt.SelectStmt.targetList[0].ResTarget.location",
"stmt.SelectStmt.targetList[0].ResTarget.val.A_Const.location",
];
const removeChangedProps = (stmt) => omit(stmt, changedProps);
expect(res.stmts.map(removeChangedProps)).to.deep.eq([
...query.parseQuerySync("select 1;").stmts.map(removeChangedProps),
...query.parseQuerySync("select null;").stmts.map(removeChangedProps),
]);
});

it("should not parse a bogus query", () => {
expect(() => query.parseQuerySync("NOT A QUERY")).to.throw(Error);
});
});

describe("Async parsing", () => {
it("should return a promise resolving to same result", async () => {
const testQuery = "select * from john;";
const resPromise = query.parseQuery(testQuery);
const res = await resPromise;

expect(resPromise).to.be.instanceof(Promise);
expect(res).to.deep.eq(query.parseQuerySync(testQuery));
});

it("should reject on bogus queries", async () => {
return query.parseQuery("NOT A QUERY").then(
() => {
throw new Error("should have rejected");
},
(e) => {
expect(e).instanceof(Error);
expect(e.message).to.match(/NOT/);
}
);
});
});

describe("Fingerprint", () => {
context("sync", () => {
it("should not fingerprint a bogus query", () => {
expect(() => query.fingerprintSync("NOT A QUERY")).to.throw(Error);
});

it("should fingerprint a query", () => {
const queries = ["select 1", "select null", "select ''", "select a, b"];
const results = queries.map(query.fingerprintSync);

results.forEach((res) => {
expect(res).to.have.lengthOf(16);
});
});
});

context("async", () => {
it("should not fingerprint a bogus query", () => {
return query.fingerprint("NOT A QUERY").then(
() => {
throw new Error("should have rejected");
},
(e) => {
expect(e).instanceof(Error);
expect(e.message).to.match(/NOT/);
}
);
});

it("should fingerprint a query", async () => {
const queries = ["select 1", "select null", "select ''", "select a, b"];
const results = await Promise.all(queries.map(query.fingerprint));

results.forEach((res) => {
expect(res).to.have.lengthOf(16);
});
});
});
});
});

describe("PlPgSQL (async)", () => {
it("should parse a function", async () => {
const testFunction = `
CREATE FUNCTION t() RETURNS trigger AS
$BODY$
DECLARE
resultVal integer;
finalVal integer;
BEGIN
resultVal = 0;
IF (resultVal >= 5)
THEN finalVal = 'Yes';
ELSE finalVal = 'No';
END IF;
RETURN finalVal;
END;
$BODY$
LANGUAGE plpgsql;
`;

const resPromise = query.parsePlPgSQL(testFunction);
const res = await resPromise;

expect(resPromise).to.be.instanceof(Promise);
expect(res).to.deep.have.property("0.PLpgSQL_function");
});
});
Loading

0 comments on commit 1efef64

Please sign in to comment.