Skip to content

Commit 28f99f0

Browse files
tianzhouclaude
andauthored
test: trim duplicated tests across unit and integration suites (#460)
* test: trim rewriter-only maxRows cases from connector integration suites The maxRows blocks in the Postgres, MySQL, MariaDB, SQL Server and SQLite integration suites had grown into near-copies of sql-row-limiter.test.ts: JOINs, window functions, plain CTEs, a CTE's inner LIMIT, data-modifying CTEs, "LIMIT higher than the cap" and "no maxRows given" all exercise the pure SQL rewriter, which the unit suite already covers case by case against a string, with no container needed. Each connector keeps the cases that need a real engine: the cap applies and flags truncation, the user's own lower LIMIT/TOP wins without a flag, non-SELECT statements are untouched, per-statement capping in a multi-statement batch, and the SQLite leading-comment regression (the connector picks all() vs run() by leading keyword). The SQLite "echoed sql is the original statement" assertion moved into the basic cap test instead of a separate copy. Also fold the scoped-package case from aws-rds-signer-missing.test.ts into the existing isDriverNotInstalled suite in load-connectors.test.ts and drop the one-off file, and point CLAUDE.md at the testing skill instead of a TESTING.md that no longer exists. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL * test: dedupe SSH, manager, cross-origin, DSN obfuscation and SafeURL unit tests Collapse same-branch cases into it.each tables and shared helpers, and drop tests whose only distinction was a different input into the same source line: - ssh-tunnel: hoist the tunnel options, add a connectWith() helper and a describe-level warn spy; drop the test that poked the private isConnected flag (the concurrent-establish test hits the same guard) and the configured-agent case already covered by the "prefer configured agent over SSH_AUTH_SOCK" test. - ssh-config-parser: parseJumpHost success and error cases become two tables; drop single/complex parseJumpHosts variants of the two-host split and a symlinked-directory IdentityFile case covered by resolveSymlink and the identity-file tests. - manager: sshSource() factory and a beforeEach establish spy; fold the alias-resolution assertions into the TOML-override test; table the SSH_AUTH_SOCK unset/set auth cases. - cross-origin: table the happy paths and the malformed Host/Origin cases; drop the wildcard-overrides-self-hosts test (the wildcard returns before self hosts are read) and the type-only getSelfHosts test. - dsn-obfuscate: one [dsn, expected] table; add the missing privateKey passthrough assertion for obfuscateSSHConfig. - safe-url: assert only the field under test; one table for the password-contains-@ cases. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL * test: table env/DSN-parser cases and move Oracle statement tests out of dsn-parser env.test.ts: resolveHost success cases, the DB_TYPE/port matrix, credential encoding and the null-return cases each become one it.each table; drop the explicit-default-port DSN test (same branch as the custom-port test), the encodeURIComponent self-test, the IPv6 host string (no IPv6 code path), the DB_* alongside TOML case (only the --dsn flag is checked) and three redactDSN cases already pinned in dsn-obfuscate.test.ts (redactDSN delegates to obfuscateDSNPassword). Import resolveSourceConfigs statically and hoist the argv save/restore. dsn-parser.test.ts: SQL Server SSL modes and the Postgres sslrootcert/sslcert/sslkey rejections become tables; the named-instance cases are covered by the password-preservation and NTLM tests; the two identical NTLM assertions merge; a writeTempPem helper replaces two inline cert fixtures. The OracleConnector splitStatements/bindsFor/convertNumber tests were never DSN-parser tests; they move verbatim to oracle.test.ts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL * test: dedupe search-objects, custom-tool, parameter-mapper and identifier-quoter tests search-objects: a search() helper plus col()/idx() fixture factories replace the per-test handler/parse boilerplate and the copy-pasted column and index literals. Drop the procedure summary case (same searchProcedures branch as the function one), the executeSQL COUNT(*) fallback test (already exercised by the summary-metadata test, which now asserts the call), and the column-pattern-with-table-filter case (both branches covered separately). Table the comment present/null, procedure/function names, default-schema scoping and LIKE pattern cases. custom-tool-handler: param() helper; drop the multi-parameter schema test (no multi-parameter branch exists); table the optional-parameter and empty-schema guards. parameter-mapper: the comment/string masking blocks re-tested stripCommentsAndStrings, which sql-parser.test.ts pins; keep one wiring test per function. Table detectParameterStyle, validateParameterStyle and the placeholder-style counting; drop the "provided values over defaults" case (value is returned before the default is consulted). identifier-quoter: quoteIdentifier has one template per quote style and no keyword or whitespace logic, so one [dbType, input, expected] table with a plain and an escape row per dialect covers it; this also adds the previously untested oracle branch. procedure-identifier-quoting.test.ts only re-ran the same function through a SHOW CREATE template and is removed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL * test: dedupe SQL parsing, readonly classification and row-limiter tests sql-parser: dialects that share a scanner (mysql/mariadb are the same scanTokenMySQL) were tested with identical input per dialect; collapse those into it.each tables, and drop splitSQLStatements cases that only re-proved scanner token boundaries already pinned by the stripCommentsAndStrings tests. allowed-keywords: remove the stale areAllStatementsReadOnly helper that mirrored a function execute-sql.ts no longer has; its multi-statement users move to sql-access-policy.test.ts as classifySQL cases. Drop the REPLACE tests that never reached the mutating check (plain SELECTs, and postgres whose pattern has no REPLACE), table the same-branch rejection groups (DML first keyword, DML in CTE, EXEC forms, PRAGMA forms, SELECT INTO, executable comments), and rewrite the string-literal test as a WITH query so it actually exercises string stripping before the check. sql-row-limiter: one shared first-guard table across all apply* entry points, tables for the hasLimitClause edge cases, placeholders and leading comments, and an INTERSECT row that the set-operation test's title promised but never had. execute-sql: mockUnreachable() helper; drop the truncated-key subset test and two readonly cases pinned by the classifier tests. readonly-transaction-strategy: failOn option and connect helpers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL * test: table the TOML loader tests and drop same-branch duplicates A loadToml() helper and a file-scope writeSource() replace the write-file/load boilerplate every test carried. The per-type field guards ("X is only supported for Y"), accept-and-echo cases, invalid value rejections, DSN-versus-field conflicts, buildDSNFromSource merge cases and the SQL Server auth rejections each become one it.each table with a row per source branch; the byte-identical explain_sql and health_check blocks become a describe.each. Dropped as duplicates of a kept test on the same branch: search_path on SQLite (same guard as the non-postgres case), authentication without an explicit type (type is derived from the DSN before validation), timeout/charset-collation "together" cases (independent validators), per-field env-interpolation copies (the recursion has no per-field branch), SQL Server param subsets of the all-parameters DSN test, readonly-only and max_rows-only custom tools, the mysql copy of the connection-fields test, and the all-database-types scenario that only asserted a count. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sx8ynn5x1z73JspkmtfVuL --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 157c774 commit 28f99f0

29 files changed

Lines changed: 1719 additions & 6054 deletions

‎CLAUDE.md‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ outside TOML and follow the same order:
180180

181181
## Testing Approach
182182

183-
See [TESTING.md](TESTING.md) for comprehensive testing documentation.
184-
185183
For detailed guidance on running and troubleshooting tests, refer to the [testing skill](.claude/skills/testing/SKILL.md). This skill is automatically activated when working with tests, test failures, or Docker/database container issues.
186184

187185
Key points:

‎src/__tests__/load-connectors.test.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ describe("isDriverNotInstalled", () => {
2020
expect(isDriverNotInstalled(err, "mysql2")).toBe(false);
2121
});
2222

23+
it("should match scoped packages", () => {
24+
const err = new Error(
25+
"Cannot find package '@aws-sdk/rds-signer' imported from /fake/path"
26+
);
27+
(err as NodeJS.ErrnoException).code = "ERR_MODULE_NOT_FOUND";
28+
29+
expect(isDriverNotInstalled(err, "@aws-sdk/rds-signer")).toBe(true);
30+
});
31+
2332
it("should return true for driver subpath imports", () => {
2433
const err = new Error(
2534
"Cannot find package 'mysql2/promise' imported from /fake/path"

0 commit comments

Comments
 (0)