{"id":20008081,"url":"https://github.com/rrwen/pg-testdb","last_synced_at":"2025-09-23T06:38:56.697Z","repository":{"id":57322655,"uuid":"105721701","full_name":"rrwen/pg-testdb","owner":"rrwen","description":"Module for PostgreSQL tests inside temporary databases","archived":false,"fork":false,"pushed_at":"2018-01-22T02:41:08.000Z","size":25,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-09T13:23:01.660Z","etag":null,"topics":["database","db","isolated","module","pg","pgtools","postgres","postgresql","tap","tape","temp","template","temporary","test","tool","unit"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/pg-testdb","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rrwen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-04T01:40:24.000Z","updated_at":"2024-12-29T14:20:03.000Z","dependencies_parsed_at":"2022-08-26T01:11:23.246Z","dependency_job_id":null,"html_url":"https://github.com/rrwen/pg-testdb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rrwen/pg-testdb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrwen%2Fpg-testdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrwen%2Fpg-testdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrwen%2Fpg-testdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrwen%2Fpg-testdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rrwen","download_url":"https://codeload.github.com/rrwen/pg-testdb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrwen%2Fpg-testdb/sbom","scorecard":{"id":786761,"data":{"date":"2025-08-11","repo":{"name":"github.com/rrwen/pg-testdb","commit":"2672cd240ce5b2783506011ad1518fabe86b5ac2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-23T06:18:13.597Z","repository_id":57322655,"created_at":"2025-08-23T06:18:13.597Z","updated_at":"2025-08-23T06:18:13.597Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275873153,"owners_count":25543752,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-19T02:00:09.700Z","response_time":108,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","db","isolated","module","pg","pgtools","postgres","postgresql","tap","tape","temp","template","temporary","test","tool","unit"],"created_at":"2024-11-13T07:08:21.968Z","updated_at":"2025-09-23T06:38:56.677Z","avatar_url":"https://github.com/rrwen.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pg-testdb\n\nRichard Wen  \nrrwen.dev@gmail.com  \n  \nModule for testing PostgreSQL queries inside isolated databases  \n\n[![npm version](https://badge.fury.io/js/pg-testdb.svg)](https://badge.fury.io/js/pg-testdb)\n[![Build Status](https://travis-ci.org/rrwen/pg-testdb.svg?branch=master)](https://travis-ci.org/rrwen/pg-testdb)\n[![Coverage Status](https://coveralls.io/repos/github/rrwen/pg-testdb/badge.svg?branch=master)](https://coveralls.io/github/rrwen/pg-testdb?branch=master)\n[![npm](https://img.shields.io/npm/dt/pg-testdb.svg)](https://www.npmjs.com/package/pg-testdb)\n[![GitHub license](https://img.shields.io/github/license/rrwen/pg-testdb.svg)](https://github.com/rrwen/pg-testdb/blob/master/LICENSE)\n[![Twitter](https://img.shields.io/twitter/url/https/github.com/rrwen/pg-testdb.svg?style=social)](https://twitter.com/intent/tweet?text=%23nodejs%20%23npm%20package%20for%20isolated%20%23postgres%20%23postgresql%20%23pg%20%23database%20%23unittest:%20https%3A%2F%2Fgithub.com%2Frrwen%2Fpg-testdb)\n\n## Install\n\n1. Install [Node.js](https://nodejs.org/en/) (v6.0.0+)\n2. Install [pg-testdb](https://www.npmjs.com/package/pg-testdb) via `npm`\n\n```\nnpm install pg-testdb --save-dev\n```\n\nFor the latest developer version, see [Developer Install](#developer-install).\n\n## Usage\n\nThe easiest way to use this package is to first install the template generator [pg-testdb-template](https://www.npmjs.com/package/pg-testdb-template) globally with `npm`:\n\n```\nnpm install -g pg-testdb-template\n\n```\n\nUse `pg-testdb-template` to generate a template file named `pg-testdb-template.js` in the current directory for editing:\n\n```\npg-testdb-template\n```\n\nThe template generated will be similar to the [Full Example](#4-full-example) provided in the [Guide](#guide).  \n  \nSee the [Guide](#guide) for more details.\n\n## Guide\n\nThis guide will help you understand how to run tests inside a test PostgreSQL database using `pg-testdb`.  \n  \nA step-by-step guide, full example, and [tape](https://www.npmjs.com/package/tape) example are provided.\n\n### Step 1. Define Connection Options\n\nFirst create an object `options` to store the temporary database name and connection details:\n\n* **testdb**: Name of the temporary database to create and test on (must not already exist)\n* **messages**: Set to `true` to enable create, drop, and error messages or `false` to disable\n* **connection**: Object containing PostgreSQL connection details\n* **connection.host**: Host IP address of the PostgreSQL database to connect to\n* **connection.port**: Port of the PostgreSQL database to connect to\n* **connection.user**: Name of PostgreSQL user with administrative privileges\n* **connection.password**: Password for `connection.user`\n\n```javascript\nvar options = {\n  testdb: 'pgtestdb',\n  messages: false,\n  connection: {\n    host: 'localhost',\n    port: 5432,\n    user: 'user_name',\n    password: 'secret_password'\n  }\n};\n```\n\n### Step 2. Define Test Queries\n\nDefine an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) `[]` of test queries to be run:\n\n* Each test query in the array is a callback function that consumes a [client](https://node-postgres.com/api/client) object from the [pg](https://www.npmjs.com/package/pg) package\n* Test queries in the array are run one after another (in order)\n\n```javascript\noptions.tests = [];\n```\n\n#### 2.1 Creating a Test Table\n\nInitialize your tests by connecting the [client](https://node-postgres.com/api/client) object and creating a table named `created_table` with columns `some_text` and `some_number`:\n\n|   some_text   |  some_number  |\n| ------------- | ------------- |\n|               |               |\n\n```javascript\noptions.tests[0] = client =\u003e {\n  client.connect();\n  return client.query('CREATE TABLE created_table (some_text text, some_number numeric);')\n    .then(() =\u003e {\n      // do something after table creation\n      console.log('Test table created!');\n    })\n    .catch(err =\u003e {\n      // handle table creation error\n      console.error('Test table creation failed.');\n    });\n};\n```\n\n#### 2.2 Inserting Values into the Test Table\n\nInsert values `'text data 1', 1), ('text data 2', 2)` into `created_table` after [its creation](#21-creating-a-test-table):\n\n|   some_text   |  some_number  |\n| ------------- | ------------- |\n| text data  1  |       1       |\n| text data  2  |       2       |\n\n```javascript\noptions.tests[1] = client =\u003e {\n  return client.query(\"INSERT INTO created_table VALUES ('text data 1', 1), ('text data 2', 2);\")\n    .then(() =\u003e {\n      // do something after insert\n      console.log('INSERT test passed!');\n    })\n    .catch(err =\u003e {\n      // handle insert error\n      console.error('INSERT test failed.');\n    });\n};\n```\n\n#### 2.3 Querying Values from the Test Table\n\nSelect all values from `created_table` after [inserting the values](#22-inserting-values-into-the-test-table):\n\n```javascript\noptions.tests[2] = client =\u003e {\n  return client.query('SELECT * FROM created_table;')\n    .then(res =\u003e {\n      // do something after select\n      console.log('SELECT test passed!');\n      console.log(res.rows[0]); // {some_text: 'text data 1', some_number: '1'}\n      console.log(res.rows[1]); // {some_text: 'text data 2', some_number: '2'}\n    })\n    .catch(err =\u003e {\n      // handle select error\n      console.log('SELECT test failed.');\n    });\n};\n```\n\n### 3. Run the Test Queries\n\nUsing the `options` object with the connection details defined from [Step 1](#step-1-define-connection-options) and test queries defined from [Step 2](#step-2-define-test-queries), the test queries can then be executed in order.  \n  \nRunning `pgtestdb` will:\n\n1. Create the temporary database [`options.testdb`](#step-1-define-connection-options)\n2. Run the [test queries](#step-2-define-test-queries)\n3. Drop the temporary database [`options.testdb`](#step-1-define-connection-options) whether tests passed or failed\n  \n```javascript\nvar pgtestdb = require('pg-testdb');\npgtestdb(options, (err, res) =\u003e {\n  // Do something after dropping the test database\n  console.log('Testing ended.');\n});\n```\n\n### 4. Full Example\n\nThe code below sets up a temporary test database in PostgreSQL and runs queries in it.  \n  \nWhen the code is executed, the following happens:\n\n1. Test database details are defined in the `options` object\n2. Test functions are defined for the test database inside the `options.tests` array\n3. Test functions in `options.tests` are run in order inside the test database named by `options.testdb`\n4. Test database is dropped after the test functions in `options.tests` are run or if an error occurs\n5. Steps 1 to 4 are repeated when the code is run again to isolate `options.tests` inside of `options.testdb`\n\n```javascript\nvar pgtestdb = require('pg-testdb');\n\n// 1. Define test database details\n// Enter your Postgres connection details below\n// The user should be have super user privileges\n// \"testdb\" is the test database, which should not already exist\nvar options = {\n  testdb: 'pgtestdb', // test db name\n  messages: false, // display info\n  connection: { // postgres connection details\n    host: 'localhost',\n    port: 5432,\n    user: 'user_name', // should be a super user\n    password: 'secret_password'\n  }\n};\n\n// 2. Define test functions\n// Add test functions to execute inside the test database in order\n// Each function has access to the client object from pg (https://www.npmjs.com/package/pg)\n// Typical usage of the object involves returning \"client.query();\"\noptions.tests = [\n\n  // 2.1 Define initial test function\n  // The first function should should run \"client.connect();\" to connect to the test database\n  // This function can be used to initialize tables for testing\n  client =\u003e {\n    client.connect(); // IMPORTANT: connect client\n    return client.query('CREATE TABLE created_table (some_text text, some_number numeric);')\n      .then(() =\u003e {\n        // Do something after table creation\n        console.log('Test table \"created_table\" created.');\n      })\n      .catch(err =\u003e {\n        // Handle table creation error\n        console.log('Test table \"created_table\" creation failed.');\n      });\n  },\n\n  // 2.2 Define second test function\n  // The second function runs after the first one succeeds\n  // This function can be used to include data into the table created from the first function\n  client =\u003e {\n    return client.query(\"INSERT INTO created_table VALUES ('text data 1', 1), ('text data 2', 2);\")\n      .then(() =\u003e {\n        // Do something after insert\n        console.log('INSERT test passed!');\n      })\n      .catch(err =\u003e {\n        // Handle insert error\n        console.log('INSERT test failed.');\n      });\n  },\n\n  // 2.3 Define third test function\n  // The third function runs after the second one succeeds\n  // This function can be used to query the inserted data from the third function\n  client =\u003e {\n    return client.query('SELECT * FROM created_table;')\n      .then(res =\u003e {\n        // Do something after select query\n        console.log('SELECT test passed!');\n        console.log(res.rows[0]); // {some_text: 'text data 1', some_number: '1'}\n        console.log(res.rows[1]); // {some_text: 'text data 2', some_number: '2'}\n      })\n      .catch(err =\u003e {\n        // Handle select query error\n        console.log('SELECT test failed.');\n      });\n  }\n\n  // 2.4 Define additional test functions\n  // Any number of functions following the above structure can be defined\n  // If a function errors out, the test database will be dropped and the error handled\n];\n\n// 3. Run test functions in test database\n// Each function in \"options.tests\" is run in order inside the defined \"options.testdb\"\n// If an error occurs, the error will be handled as defined and the test database dropped\n// Re-running this with the defined \"options\" will recreate the test database and run the test functions inside it\npgtestdb(options, (err, res) =\u003e {\n\n  // 4. Drop test database\n  // The test database is dropped if all tests succeed or if an error occurs\n  // Do something after dropping the test database\n  console.log('Test database \"pgtestdb\" dropped.');\n});\n```\n\nThis example can be generated with [pg-testdb-template](https://www.npmjs.com/package/pg-testdb-template) as shown in [Usage](#usage).\n\n### 5. Example with tape\n\nA testing framework such as [tape](https://www.npmjs.com/package/tape) can be used with `pg-testdb` such that the test functions and execution is inside tape's test function call:\n\n```javascript\nvar pgtestdb = require('pg-testdb');\nvar test = require('tape');\n\n// (test_db) Define a test database\nvar options = {\n  testdb: 'pgtestdb', // test db name\n  messages: false, // display info\n  connection: { // postgres connection details\n    host: 'localhost',\n    port: 5432,\n    user: 'user_name', // should be an admin user\n    password: 'secret_password'\n  }\n};\n\n// (test_tape) Define test functions and run inside tape\ntest('Tests for tape example', t =\u003e {\n\n  // (test_functions) Define test functions\n  options.tests = [\n\n    // (test_init) Connect client and create test table\n    client =\u003e {\n      client.connect();\n      return client.query('CREATE TABLE created_table (some_text text, some_number numeric);')\n        .then(() =\u003e {\n          t.pass('Test table \"created_table\" created.');\n        })\n        .catch(err =\u003e {\n          t.fail('Test table \"created_table\" creation failed.');\n        });\n    },\n\n    // (test_1) Test inserts into test table\n    client =\u003e {\n      return client.query(\"INSERT INTO created_table VALUES ('text data 1', 1), ('text data 2', 2);\")\n        .then(() =\u003e {\n          t.pass('INSERT test passed!');\n        })\n        .catch(err =\u003e {\n          t.fail('INSERT test failed.');\n        });\n    },\n\n    // (test_2) Test select query on test table\n    client =\u003e {\n      return client.query('SELECT * FROM created_table;')\n        .then(res =\u003e {\n          t.pass('SELECT test passed!');\n        })\n        .catch(err =\u003e {\n          t.fail('SELECT test failed.');\n        });\n    }\n  ];\n\n  // (test_run) Run the tests\n  pgtestdb(options, (err, res) =\u003e {\n    t.comment('Test database \"pgtestdb\" dropped.');\n  });\n});\n```\n\nSee [tests/test.js](https://github.com/rrwen/pg-testdb/blob/master/tests/test.js) for more examples with tape.\n\n## Developer Notes\n\n### Developer Install\n\nInstall the latest developer version with `npm` from github:\n\n```\nnpm install git+https://github.com/rrwen/pg-testdb\n```\n  \nInstall from `git` cloned source:\n\n1. Ensure [git](https://git-scm.com/) is installed\n2. Clone into current path\n3. Install via `npm`\n\n```\ngit clone https://github.com/rrwen/pg-testdb\ncd pg-testdb\nnpm install\n```\n\n### Tests\n\n1. Clone into current path `git clone https://github.com/rrwen/pg-testdb`\n2. Enter into folder `cd pg-testdb`\n3. Ensure [tape](https://www.npmjs.com/package/tape) and [moment](https://www.npmjs.com/package/moment) are available\n4. Setup test environment (See [tests/README.md](https://github.com/rrwen/pg-testdb/blob/master/tests/README.md))\n5. Run tests\n6. Results are saved to `./tests/log` with each file corresponding to a version tested\n\n```\nnpm install\nnpm test\n```\n\n### Upload to Github\n\n1. Ensure [git](https://git-scm.com/) is installed\n2. Inside the `pg-testdb` folder, add all files and commit changes\n3. Push to github\n\n```\ngit add .\ngit commit -a -m \"Generic update\"\ngit push\n```\n\n### Upload to npm\n\n1. Update the version in `package.json`\n2. Run tests and check for OK status\n3. Login to npm\n4. Publish to npm\n\n```\nnpm test\nnpm login\nnpm publish\n```\n\n### Implementation\n\nThe [npm](https://www.npmjs.com/) package [pg-testdb](https://www.npmjs.com/package/pg-testdb) was implemented with [pg](https://www.npmjs.com/package/pg) and [pgtools](https://www.npmjs.com/package/pgtools). `pg` was used for creating client connections to PostgreSQL databases in [Node.js](https://nodejs.org/), while `pgtools` was used to temporarily create and drop PostgreSQL databases:\n\n1. Create a temporary database with `pgtools`\n2. Create a client connection to the temporary database with `pg`\n3. Drop the temporary database with `pgtools`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frrwen%2Fpg-testdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frrwen%2Fpg-testdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frrwen%2Fpg-testdb/lists"}