Repository navigation
Expand file tree
/
Copy pathselect-functions.test.ts
More file actions
135 lines (120 loc) · 3.95 KB
/
Copy pathselect-functions.test.ts
File metadata and controls
135 lines (120 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { describe, expect, it, vi } from "vitest"
import { queryBuilder } from "../../../src/query/query-builder.js"
import type { Input, Schema } from "../../../src/query/types.js"
// Test schema
interface Employee extends Input {
id: number
name: string
department_id: number
salary: number
}
interface Department extends Input {
id: number
name: string
budget: number
location: string
}
// Make sure TestSchema extends Schema
interface TestSchema extends Schema {
employees: Employee
departments: Department
}
describe(`QueryBuilder.select with function calls`, () => {
it(`handles aggregate functions without using `, () => {
const query = queryBuilder<TestSchema>()
.from(`employees`)
.select(`@id`, {
sum_salary: { SUM: `@salary` },
avg_salary: { AVG: `@salary` },
count: { COUNT: `@id` },
min_salary: { MIN: `@salary` },
max_salary: { MAX: `@salary` },
})
const builtQuery = query._query
expect(builtQuery.select).toMatchObject([
`@id`,
{
sum_salary: { SUM: `@salary` },
avg_salary: { AVG: `@salary` },
count: { COUNT: `@id` },
min_salary: { MIN: `@salary` },
max_salary: { MAX: `@salary` },
},
])
})
it(`handles string functions without using `, () => {
const query = queryBuilder<TestSchema>()
.from(`employees`)
.select(`@id`, {
upper_name: { UPPER: `@name` },
lower_name: { LOWER: `@name` },
name_length: { LENGTH: `@name` },
concat_text: { CONCAT: [`Employee: `, `@name`] },
})
const builtQuery = query._query
expect(builtQuery.select).toMatchObject([
`@id`,
{
upper_name: { UPPER: `@name` },
lower_name: { LOWER: `@name` },
name_length: { LENGTH: `@name` },
concat_text: { CONCAT: [`Employee: `, `@name`] },
},
])
})
it(`handles JSON functions without using `, () => {
// Create a field that would contain JSON
const query = queryBuilder<TestSchema>()
.from(`employees`)
.select(`@id`, {
json_value: { JSON_EXTRACT: [`@name`, `$.property`] },
})
const builtQuery = query._query
expect(builtQuery.select).toHaveLength(2)
// Non-null assertion since we've already checked the length
expect(builtQuery.select![1]).toHaveProperty(`json_value`)
})
it(`validates and filters out invalid function calls`, () => {
// Mock console.warn to verify warnings
const consoleWarnMock = vi
.spyOn(console, `warn`)
.mockImplementation(() => {})
queryBuilder<TestSchema>()
.from(`employees`)
.select(`@id`, {
// This is an invalid function that should trigger a warning
// @ts-expect-error
invalid_func: { INVALID_FUNCTION: `@name` },
})
// Verify the warning was logged
expect(consoleWarnMock).toHaveBeenCalledWith(
expect.stringContaining(`Unsupported function: INVALID_FUNCTION`)
)
// Restore the original console.warn
consoleWarnMock.mockRestore()
})
it(`combines function calls with other select elements`, () => {
const query = queryBuilder<TestSchema>()
.from(`employees`, `e`)
.join({
type: `inner`,
from: `departments`,
as: `d`,
on: [`@e.department_id`, `=`, `@d.id`],
})
.select(`@e.id`, `@e.name`, `@d.name`, {
dept_budget: `@d.budget`,
sum_salary: { SUM: `@e.salary` },
upper_name: { UPPER: `@e.name` },
})
const builtQuery = query._query
expect(builtQuery.select).toHaveLength(4)
// Non-null assertions since we've already checked the length
expect(builtQuery.select![0]).toBe(`@e.id`)
expect(builtQuery.select![1]).toBe(`@e.name`)
expect(builtQuery.select![2]).toBe(`@d.name`)
expect(builtQuery.select![3]).toHaveProperty(`dept_budget`)
expect(builtQuery.select![3]).toHaveProperty(`sum_salary`)
expect(builtQuery.select![3]).toHaveProperty(`upper_name`)
})
})