1+ import { ObjectId } from 'mongodb' ;
2+ import { testSetup } from './test-setup' ;
3+
4+ describe ( 'Edge Cases Integration Tests' , ( ) => {
5+ beforeAll ( async ( ) => {
6+ await testSetup . init ( ) ;
7+ } , 30000 ) ; // 30 second timeout for container startup
8+
9+ afterAll ( async ( ) => {
10+ // Make sure to close any outstanding connections
11+ const squongo = testSetup . getSquongo ( ) ;
12+
13+ // Clean up any resources that squongo might be using
14+ if ( typeof squongo . close === 'function' ) {
15+ await squongo . close ( ) ;
16+ }
17+
18+ // Clean up test setup resources
19+ await testSetup . cleanup ( ) ;
20+ } , 10000 ) ; // Give it more time to clean up
21+
22+ beforeEach ( async ( ) => {
23+ // Clean up collections before each test
24+ const db = testSetup . getDb ( ) ;
25+ await db . collection ( 'edge_test' ) . deleteMany ( { } ) ;
26+ await db . collection ( 'missing_collection' ) . deleteMany ( { } ) ;
27+ } ) ;
28+
29+ afterEach ( async ( ) => {
30+ // Clean up collections after each test
31+ const db = testSetup . getDb ( ) ;
32+ await db . collection ( 'edge_test' ) . deleteMany ( { } ) ;
33+ } ) ;
34+
35+ test ( 'should handle special characters in field names' , async ( ) => {
36+ // Arrange
37+ const db = testSetup . getDb ( ) ;
38+ await db . collection ( 'edge_test' ) . insertMany ( [
39+ { 'field_with_underscores' : 'value1' , name : 'item1' } ,
40+ { 'field_with_numbers123' : 'value2' , name : 'item2' } ,
41+ { 'UPPERCASE_FIELD' : 'value3' , name : 'item3' } ,
42+ { 'mixedCaseField' : 'value4' , name : 'item4' } ,
43+ { 'snake_case_field' : 'value5' , name : 'item5' }
44+ ] ) ;
45+
46+ // Act
47+ const squongo = testSetup . getSquongo ( ) ;
48+ // Since SQL parsers often have issues with special characters, we'll use identifiers that are more likely
49+ // to be supported by most SQL parsers
50+ const sql = 'SELECT name, field_with_underscores FROM edge_test WHERE field_with_underscores = "value1"' ;
51+
52+ const results = await squongo . execute ( sql ) ;
53+
54+ // Assert
55+ expect ( results ) . toHaveLength ( 1 ) ;
56+ expect ( results [ 0 ] . name ) . toBe ( 'item1' ) ;
57+ expect ( results [ 0 ] . field_with_underscores ) . toBe ( 'value1' ) ;
58+ } ) ;
59+
60+ test ( 'should gracefully handle invalid SQL syntax' , async ( ) => {
61+ // Arrange
62+ const squongo = testSetup . getSquongo ( ) ;
63+ const invalidSql = 'SELECT FROM users WHERE;' ; // Missing column and invalid WHERE clause
64+
65+ // Act & Assert
66+ await expect ( squongo . execute ( invalidSql ) ) . rejects . toThrow ( ) ;
67+ } ) ;
68+
69+ test ( 'should gracefully handle valid SQL but unsupported features' , async ( ) => {
70+ // Arrange
71+ const squongo = testSetup . getSquongo ( ) ;
72+ // SQL with PIVOT which is not widely supported in most SQL implementations
73+ const unsupportedSql = 'SELECT * FROM (SELECT category, price FROM products) PIVOT (SUM(price) FOR category IN ("Electronics", "Furniture"))' ;
74+
75+ // Act & Assert
76+ await expect ( squongo . execute ( unsupportedSql ) ) . rejects . toThrow ( ) ;
77+ } ) ;
78+
79+ test ( 'should handle behavior with missing collections' , async ( ) => {
80+ // Arrange
81+ const squongo = testSetup . getSquongo ( ) ;
82+ const sql = 'SELECT * FROM nonexistent_collection' ;
83+
84+ // Act
85+ const results = await squongo . execute ( sql ) ;
86+
87+ // Assert - should return empty array rather than throwing an error
88+ expect ( Array . isArray ( results ) ) . toBe ( true ) ;
89+ expect ( results ) . toHaveLength ( 0 ) ;
90+ } ) ;
91+
92+ test ( 'should handle invalid data types appropriately' , async ( ) => {
93+ // Arrange
94+ const db = testSetup . getDb ( ) ;
95+ await db . collection ( 'edge_test' ) . insertMany ( [
96+ { name : 'item1' , value : 123 } ,
97+ { name : 'item2' , value : 'not a number' }
98+ ] ) ;
99+
100+ // Act
101+ const squongo = testSetup . getSquongo ( ) ;
102+ // Try to do numerical comparison on non-numeric data
103+ const sql = 'SELECT name FROM edge_test WHERE value > 100' ;
104+
105+ const results = await squongo . execute ( sql ) ;
106+
107+ // Assert - should only find the numeric value that's valid for comparison
108+ expect ( results ) . toHaveLength ( 1 ) ;
109+ expect ( results [ 0 ] . name ) . toBe ( 'item1' ) ;
110+ } ) ;
111+
112+ test ( 'should handle MongoDB ObjectId conversions' , async ( ) => {
113+ // Arrange
114+ const db = testSetup . getDb ( ) ;
115+ const objectId = new ObjectId ( ) ;
116+ await db . collection ( 'edge_test' ) . insertOne ( {
117+ _id : objectId ,
118+ name : 'ObjectId Test'
119+ } ) ;
120+
121+ // Act
122+ const squongo = testSetup . getSquongo ( ) ;
123+ // Use the string representation of ObjectId in SQL
124+ const sql = `SELECT name FROM edge_test WHERE _id = '${ objectId . toString ( ) } '` ;
125+
126+ const results = await squongo . execute ( sql ) ;
127+
128+ // Assert
129+ expect ( results ) . toHaveLength ( 1 ) ;
130+ expect ( results [ 0 ] . name ) . toBe ( 'ObjectId Test' ) ;
131+ } ) ;
132+
133+ test ( 'should handle extremely large result sets' , async ( ) => {
134+ // Arrange
135+ const db = testSetup . getDb ( ) ;
136+ const largeDataset = Array . from ( { length : 1000 } , ( _ , i ) => ( {
137+ index : i ,
138+ name : `Item ${ i } ` ,
139+ value : Math . random ( ) * 1000
140+ } ) ) ;
141+
142+ await db . collection ( 'edge_test' ) . insertMany ( largeDataset ) ;
143+
144+ // Act
145+ const squongo = testSetup . getSquongo ( ) ;
146+ const sql = 'SELECT * FROM edge_test' ;
147+
148+ const results = await squongo . execute ( sql ) ;
149+
150+ // Assert
151+ expect ( results ) . toHaveLength ( 1000 ) ;
152+ expect ( results [ 0 ] ) . toHaveProperty ( 'index' ) ;
153+ expect ( results [ 0 ] ) . toHaveProperty ( 'name' ) ;
154+ expect ( results [ 0 ] ) . toHaveProperty ( 'value' ) ;
155+ } ) ;
156+ } ) ;
0 commit comments