Skip to content

Commit cbc4253

Browse files
Copilotmk3008
andcommitted
Implement ParameterRemover utility and tests
Co-authored-by: mk3008 <[email protected]>
1 parent eaea195 commit cbc4253

File tree

4 files changed

+1330
-0
lines changed

4 files changed

+1330
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ A suite of utilities for transforming and analyzing SQL ASTs.
421421
Consolidates all CTEs into a single root-level WITH clause. Throws an error if duplicate CTE names with different definitions are found.
422422
- **QueryNormalizer**
423423
Converts any SELECT/UNION/VALUES query into a standard SimpleSelectQuery. Handles subquery wrapping and automatic column name generation.
424+
- **ParameterRemover**
425+
Removes ParameterExpression nodes (parameterized expressions) from SQL AST. Useful for creating non-parameterized query variations or for static analysis. For compound logical expressions (AND/OR), only the parameterized parts are removed while preserving the rest of the query structure. Works recursively across subqueries, CTEs, and other nested structures.
424426

425427
- **QueryBuilder**
426428
Converts any SELECT/UNION/VALUES query into a standard SimpleSelectQuery. Handles subquery wrapping and automatic column name generation.
@@ -518,6 +520,24 @@ console.log(sqlTemp);
518520
// => create temporary table "tmp_table" as select "id", "name" from "users"
519521
```
520522

523+
```typescript
524+
// Parameter Removal Example
525+
import { SelectQueryParser, ParameterRemover, SqlFormatter } from 'rawsql-ts';
526+
527+
// Parse a query with parameters
528+
const sql = `SELECT id, name FROM users WHERE active = true AND department = :dept AND created_at > :date`;
529+
const query = SelectQueryParser.parse(sql);
530+
531+
// Remove parameter expressions
532+
const nonParamQuery = ParameterRemover.remove(query);
533+
534+
// Format the result
535+
const formatter = new SqlFormatter();
536+
const result = formatter.format(nonParamQuery).formattedSql;
537+
console.log(result);
538+
// => select "id", "name" from "users" where "active" = true
539+
```
540+
521541
```typescript
522542
// Retrieves physical table sources.
523543
const tableSourceCollector = new TableSourceCollector();

docs/test-policy.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Test Policy
2+
3+
This document outlines the testing strategy for the rawsql-ts library.
4+
5+
## Types of Tests
6+
7+
We use two main types of tests:
8+
9+
1. **Unit Tests**: These tests verify individual components in isolation, focusing on a specific functionality of a single class or function.
10+
2. **Integration Tests**: These tests verify how multiple components work together, often including parsing from SQL strings, transforming, and formatting back to SQL.
11+
12+
## Test File Structure
13+
14+
- Tests should be located in the `tests` directory, mirroring the structure of the `src` directory.
15+
- Test files should be named with the pattern `[component-name].test.ts`.
16+
- For utilities and transformers, use the pattern `tests/[directory]/[utility-name].test.ts`.
17+
18+
## Test Frameworks and Tools
19+
20+
- We use [Vitest](https://vitest.dev/) as the test runner.
21+
- Tests should use standard assertion methods provided by Vitest.
22+
23+
## Test Organization
24+
25+
Tests should be organized using `describe` blocks to group related tests:
26+
27+
```typescript
28+
describe('Component', () => {
29+
describe('method or functionality', () => {
30+
test('specific behavior or case', () => {
31+
// Test code
32+
});
33+
});
34+
});
35+
```
36+
37+
## Test Approach for SQL Components
38+
39+
For utilities and transformers that work with SQL AST components, we recommend a two-level testing approach:
40+
41+
1. **SqlComponent-level unit tests**: These test the utility using manually constructed AST nodes. These tests are precise and clearly show the expected behavior.
42+
43+
2. **Query-level integration tests**: These test the utility by:
44+
- Parsing SQL from a string
45+
- Applying the transformation
46+
- Formatting back to SQL
47+
- Asserting on the resulting SQL string
48+
49+
This approach ensures both that the internal logic works correctly and that the utility integrates properly with the SQL parser and formatter.
50+
51+
## Example
52+
53+
```typescript
54+
describe('MyUtility', () => {
55+
describe('SqlComponent-level unit tests', () => {
56+
test('handles specific case', () => {
57+
// Create AST manually
58+
const node = new SomeComponent(/* ... */);
59+
60+
// Apply transformation
61+
const result = MyUtility.transform(node);
62+
63+
// Assert on the result
64+
expect(result).toBeInstanceOf(SomeComponent);
65+
expect(result.property).toBe(expectedValue);
66+
});
67+
});
68+
69+
describe('query-level integration tests', () => {
70+
test('transforms SQL correctly', () => {
71+
// Parse SQL
72+
const sql = `SELECT * FROM users WHERE id = 1`;
73+
const query = SelectQueryParser.parse(sql);
74+
75+
// Apply transformation
76+
const result = MyUtility.transform(query);
77+
78+
// Format back to SQL
79+
const formatter = new Formatter();
80+
const resultSql = formatter.format(result);
81+
82+
// Assert on the resulting SQL
83+
expect(resultSql).toBe(expectedSql);
84+
});
85+
});
86+
});
87+
```
88+
89+
## Test Coverage
90+
91+
- Aim for high test coverage, particularly for complex transformations and utilities.
92+
- Test both normal cases and edge cases.
93+
- For complex operations, test compound cases with multiple features interacting.
94+
95+
## Testing New Features
96+
97+
When adding a new feature:
98+
99+
1. Start by writing tests that define the expected behavior.
100+
2. Implement the feature to make the tests pass.
101+
3. Include both SqlComponent-level unit tests and query-level integration tests.
102+
4. Consider edge cases and add tests for them.
103+
104+
This test-driven approach helps ensure that features are well-defined and correctly implemented.

0 commit comments

Comments
 (0)