lone-format 0.9.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,61 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- // INSERT 示例(一行压缩格式)
4
- const insertSql = `-- INSERT statement
5
- INSERT INTO users (username, email, password, status, created_at) VALUES ( 'john_doe', 'john@example.com', 'hashed_password_123', 'active', NOW () ), ( 'jane_smith', 'jane@example.com', 'hashed_password_456', 'active', NOW () ), ( 'bob_wilson', 'bob@example.com', 'hashed_password_789', 'pending', NOW () );`
6
-
7
- const expected = `-- INSERT statement
8
- INSERT INTO
9
- users (username, email, password, status, created_at)
10
- VALUES
11
- (
12
- 'john_doe',
13
- 'john@example.com',
14
- 'hashed_password_123',
15
- 'active',
16
- NOW ()
17
- ),
18
- (
19
- 'jane_smith',
20
- 'jane@example.com',
21
- 'hashed_password_456',
22
- 'active',
23
- NOW ()
24
- ),
25
- (
26
- 'bob_wilson',
27
- 'bob@example.com',
28
- 'hashed_password_789',
29
- 'pending',
30
- NOW ()
31
- );`
32
-
33
- console.log('=== 输入 SQL ===')
34
- console.log(insertSql)
35
-
36
- console.log('\n=== 当前格式化结果 ===')
37
- const formatted = formatSql(insertSql, { tabWidth: 2, keywordCase: 'upper' })
38
- console.log(formatted)
39
-
40
- console.log('\n=== 期望结果 ===')
41
- console.log(expected)
42
-
43
- console.log('\n=== 对比 ===')
44
- console.log('是否匹配:', formatted === expected ? 'YES ✓' : 'NO ✗')
45
-
46
- if (formatted !== expected) {
47
- console.log('\n=== 差异分析 ===')
48
- const formattedLines = formatted.split('\n')
49
- const expectedLines = expected.split('\n')
50
- const maxLines = Math.max(formattedLines.length, expectedLines.length)
51
-
52
- for (let i = 0; i < maxLines; i++) {
53
- const fLine = formattedLines[i] || ''
54
- const eLine = expectedLines[i] || ''
55
- if (fLine !== eLine) {
56
- console.log(`Line ${i + 1} 不同:`)
57
- console.log(` 当前: ${JSON.stringify(fLine)}`)
58
- console.log(` 期望: ${JSON.stringify(eLine)}`)
59
- }
60
- }
61
- }
@@ -1,19 +0,0 @@
1
- const sql = `-- INSERT statement
2
- INSERT INTO users (username, email, password, status, created_at) VALUES ( 'john_doe', 'john@example.com', 'hashed_password_123', 'active', NOW () ), ( 'jane_smith', 'jane@example.com', 'hashed_password_456', 'active', NOW () ), ( 'bob_wilson', 'bob@example.com', 'hashed_password_789', 'pending', NOW () );`
3
-
4
- const regex = /\b(INSERT\s+INTO)\s+(\w+)\s*\(([^)]+)\)\s*(VALUES)\s*(.+?)(?=;|$)/gis
5
-
6
- const match = regex.exec(sql)
7
-
8
- console.log('=== 正则匹配测试 ===')
9
- console.log('匹配结果:', match ? '成功' : '失败')
10
-
11
- if (match) {
12
- console.log('\n捕获组:')
13
- console.log('0 (完整匹配):', JSON.stringify(match[0].substring(0, 100)) + '...')
14
- console.log('1 (INSERT INTO):', match[1])
15
- console.log('2 (表名):', match[2])
16
- console.log('3 (列名):', match[3])
17
- console.log('4 (VALUES):', match[4])
18
- console.log('5 (值内容):', JSON.stringify(match[5].substring(0, 100)) + '...')
19
- }
@@ -1,40 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const joinQuery = `-- JOIN query with multiple tables
4
- SELECT u.id, u.username, u.email, p.title AS post_title, p.created_at AS post_date, COUNT(c.id) AS comment_count FROM users u INNER JOIN posts p ON u.id = p.user_id LEFT JOIN comments c ON p.id = c.post_id WHERE u.status = 'active' AND p.published = TRUE GROUP BY u.id, u.username, u.email, p.title, p.created_at HAVING COUNT(c.id) > 5 ORDER BY comment_count DESC;`
5
-
6
- const expected = `-- JOIN query with multiple tables
7
- SELECT
8
- u.id,
9
- u.username,
10
- u.email,
11
- p.title AS post_title,
12
- p.created_at AS post_date,
13
- COUNT(c.id) AS comment_count
14
- FROM
15
- users u
16
- INNER JOIN posts p ON u.id = p.user_id
17
- LEFT JOIN comments c ON p.id = c.post_id
18
- WHERE
19
- u.status = 'active'
20
- AND p.published = TRUE
21
- GROUP BY
22
- u.id,
23
- u.username,
24
- u.email,
25
- p.title,
26
- p.created_at
27
- HAVING
28
- COUNT(c.id) > 5
29
- ORDER BY
30
- comment_count DESC;`
31
-
32
- console.log('=== Input SQL ===')
33
- console.log(joinQuery)
34
- console.log('\n=== Current Formatted Result ===')
35
- const formatted = formatSql(joinQuery, { tabWidth: 2, keywordCase: 'upper' })
36
- console.log(formatted)
37
- console.log('\n=== Expected Result ===')
38
- console.log(expected)
39
- console.log('\n=== Match ===')
40
- console.log(formatted === expected ? 'YES ✓' : 'NO ✗')
@@ -1,40 +0,0 @@
1
- import { formatSql, parseSqlClauses, tokenizeSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- // 测试 JOIN 示例(来自 App.vue)
4
- const joinExample = `-- JOIN query with multiple tables
5
- SELECT
6
- u.id,
7
- u.username,
8
- u.email,
9
- p.title as post_title,
10
- p.created_at as post_date,
11
- COUNT(c.id) as comment_count
12
- FROM users u
13
- INNER JOIN posts p ON u.id = p.user_id
14
- LEFT JOIN comments c ON p.id = c.post_id
15
- WHERE u.status = 'active'
16
- AND p.published = true
17
- GROUP BY u.id, u.username, u.email, p.title, p.created_at
18
- HAVING COUNT(c.id) > 5
19
- ORDER BY comment_count DESC;`
20
-
21
- console.log('=== 原始 JOIN 示例 ===')
22
- console.log(joinExample)
23
- console.log('\n=== 格式化后 ===')
24
- const formatted = formatSql(joinExample, { tabWidth: 2, keywordCase: 'upper' })
25
- console.log(formatted)
26
-
27
- console.log('\n=== 解析子句 ===')
28
- const parsed = parseSqlClauses(joinExample)
29
- parsed.clauses.forEach((clause, i) => {
30
- console.log(`\nClause ${i}: ${clause.type}`)
31
- console.log('Content:')
32
- console.log(clause.content)
33
- console.log('---')
34
- })
35
-
36
- console.log('\n=== Token化测试(第一个SELECT字段)===')
37
- const selectLine = ' u.id,'
38
- const tokens = tokenizeSql(selectLine)
39
- console.log('Line:', JSON.stringify(selectLine))
40
- console.log('Tokens:', tokens.map(t => ({ type: t.type, value: JSON.stringify(t.value) })))
package/dist/test-join.ts DELETED
@@ -1,35 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const input = `-- JOIN query with multiple tables
4
- SELECT u.id, u.username, u.email, p.title AS post_title, p.created_at AS post_date, COUNT(c.id) AS comment_count FROM users u INNER JOIN posts p ON u.id = p.user_id LEFT JOIN comments c ON p.id = c.post_id WHERE u.status = 'active' AND p.published = TRUE GROUP BY u.id, u.username, u.email, p.title, p.created_at HAVING COUNT(c.id) > 5 ORDER BY comment_count DESC;`;
5
-
6
- const result = formatSql(input, { tabWidth: 2, keywordCase: 'upper' });
7
-
8
- console.log('===== Current Formatted SQL =====');
9
- console.log(result);
10
- console.log('\n===== Expected SQL =====');
11
- console.log(`-- JOIN query with multiple tables
12
- SELECT
13
- u.id,
14
- u.username,
15
- u.email,
16
- p.title AS post_title,
17
- p.created_at AS post_date,
18
- COUNT(c.id) AS comment_count
19
- FROM
20
- users u
21
- INNER JOIN posts p ON u.id = p.user_id
22
- LEFT JOIN comments c ON p.id = c.post_id
23
- WHERE
24
- u.status = 'active'
25
- AND p.published = TRUE
26
- GROUP BY
27
- u.id,
28
- u.username,
29
- u.email,
30
- p.title,
31
- p.created_at
32
- HAVING
33
- COUNT(c.id) > 5
34
- ORDER BY
35
- comment_count DESC;`);
@@ -1,55 +0,0 @@
1
- import { parseSqlClauses } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const sql = "UPDATE users SET status = 'inactive', updated_at = NOW(), last_login = NULL WHERE last_login < DATE_SUB(NOW(), INTERVAL 6 MONTH) AND status = 'active';"
4
-
5
- console.log('=== Testing parseSqlClauses ===\n')
6
- console.log('Input SQL:')
7
- console.log(sql)
8
- console.log('\n' + '='.repeat(70) + '\n')
9
-
10
- const parsed = parseSqlClauses(sql)
11
-
12
- console.log(`Found ${parsed.clauses.length} clauses:\n`)
13
-
14
- parsed.clauses.forEach((clause, idx) => {
15
- console.log(`Clause ${idx + 1}: [${clause.type}]`)
16
- console.log(` collapsible: ${clause.collapsible}`)
17
- console.log(` content lines: ${clause.content.split('\n').length}`)
18
- console.log(` content:`)
19
-
20
- const lines = clause.content.split('\n')
21
- lines.forEach((line, lineIdx) => {
22
- const spaces = (line.match(/^(\s*)/) || ['', ''])[1].length
23
- const visual = line.replace(/ /g, '·')
24
- console.log(` ${lineIdx + 1}. (${spaces}sp) "${visual}"`)
25
- })
26
-
27
- console.log('')
28
- })
29
-
30
- console.log('='.repeat(70) + '\n')
31
-
32
- // 检查 UPDATE 子句的 SET 字段缩进
33
- const updateClause = parsed.clauses.find(c => c.type === 'UPDATE')
34
- if (updateClause) {
35
- const lines = updateClause.content.split('\n')
36
- const setLineIdx = lines.findIndex(l => l.trim() === 'SET')
37
-
38
- if (setLineIdx !== -1 && setLineIdx + 1 < lines.length) {
39
- const firstField = lines[setLineIdx + 1]
40
- const spaces = (firstField.match(/^(\s*)/) || ['', ''])[1].length
41
-
42
- console.log(`UPDATE clause analysis:`)
43
- console.log(` SET keyword at line ${setLineIdx + 1}`)
44
- console.log(` First SET field at line ${setLineIdx + 2}: "${firstField}"`)
45
- console.log(` Leading spaces: ${spaces}`)
46
-
47
- if (spaces === 2) {
48
- console.log(` ✅ Correct! SET fields have 2-space indentation`)
49
- } else if (spaces === 0) {
50
- console.log(` ❌ ERROR! SET fields have NO indentation`)
51
- } else {
52
- console.log(` ⚠️ Unexpected: ${spaces}-space indentation`)
53
- }
54
- }
55
- }
@@ -1,34 +0,0 @@
1
- import { XMLParser } from 'fast-xml-parser'
2
-
3
- const xml = `<?xml version="1.0" encoding="UTF-8"?>
4
- <!-- 这是图书馆的 XML 数据 -->
5
- <library>
6
- <!-- 第一本书:TypeScript -->
7
- <book id="1" category="programming">
8
- <title lang="en">Learning TypeScript</title>
9
- <author>Josh Goldberg</author>
10
- <year>2022</year>
11
- <price currency="USD">39.99</price>
12
- <example><![CDATA[const add = (a, b) => a + b; console.log(add(2, 3)); // 5]]></example>
13
- </book>
14
-
15
- <!-- 第二本书:Vue.js -->
16
- <book id="2" category="web">
17
- <title lang="en">Vue.js 3 Cookbook</title>
18
- <author>Heitor Ramon Ribeiro</author>
19
- <year>2023</year>
20
- <price currency="USD">44.99</price>
21
- </book>
22
- </library>`
23
-
24
- console.log('===== preserveOrder: true =====')
25
- const parser2 = new XMLParser({
26
- ignoreAttributes: false,
27
- attributeNamePrefix: '@_',
28
- textNodeName: '#text',
29
- ignoreDeclaration: false,
30
- commentPropName: '#comment',
31
- cdataPropName: '__cdata',
32
- preserveOrder: true,
33
- })
34
- console.log(JSON.stringify(parser2.parse(xml), null, 2))
@@ -1,43 +0,0 @@
1
- const sql = `CREATE TABLE IF NOT EXISTS orders ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, order_number VARCHAR(50) NOT NULL, total_amount DECIMAL(10, 2) NOT NULL, status ENUM ('pending', 'processing', 'completed', 'cancelled') DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_number (order_number), KEY idx_user_id (user_id), KEY idx_status (status), KEY idx_created_at (created_at), CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;`
2
-
3
- // 当前的正则(非贪婪)
4
- const regex1 = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)\s*\(([\s\S]*?)\)\s*([^;]*);/gi
5
-
6
- console.log('=== 测试当前正则(非贪婪匹配) ===')
7
- const match1 = regex1.exec(sql)
8
- if (match1) {
9
- console.log('匹配成功!')
10
- console.log('表名:', match1[1])
11
- console.log('列定义长度:', match1[2].length)
12
- console.log('列定义内容:', match1[2].substring(0, 200) + '...')
13
- console.log('表后缀:', match1[3])
14
- } else {
15
- console.log('匹配失败!')
16
- }
17
-
18
- console.log('\n=== 手动查找括号匹配 ===')
19
- // 找到 CREATE TABLE ... ( 的位置
20
- const createTableMatch = sql.match(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)\s*\(/i)
21
- if (createTableMatch) {
22
- const startPos = createTableMatch.index + createTableMatch[0].length
23
- console.log('左括号位置:', startPos)
24
-
25
- // 从左括号开始,手动匹配到对应的右括号
26
- let depth = 1
27
- let pos = startPos
28
- while (pos < sql.length && depth > 0) {
29
- if (sql[pos] === '(') depth++
30
- else if (sql[pos] === ')') depth--
31
- pos++
32
- }
33
-
34
- console.log('右括号位置:', pos - 1)
35
- console.log('列定义长度:', pos - startPos - 1)
36
-
37
- const columnsDef = sql.substring(startPos, pos - 1)
38
- console.log('列定义内容:', columnsDef.substring(0, 200) + '...')
39
-
40
- // 检查是否包含所有列
41
- const hasAllColumns = columnsDef.includes('CONSTRAINT fk_orders_user')
42
- console.log('包含 CONSTRAINT:', hasAllColumns)
43
- }
@@ -1,77 +0,0 @@
1
- import { parseSqlClauses, tokenizeSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const sql = "UPDATE users SET status = 'inactive', updated_at = NOW(), last_login = NULL WHERE last_login < DATE_SUB(NOW(), INTERVAL 6 MONTH) AND status = 'active';"
4
-
5
- console.log('=== Simulating Vue Component Rendering ===\n')
6
-
7
- const parsed = parseSqlClauses(sql)
8
- const updateClause = parsed.clauses[0]
9
-
10
- console.log('UPDATE clause content:')
11
- console.log(updateClause.content)
12
- console.log('\n' + '='.repeat(70) + '\n')
13
-
14
- // 模拟 getClauseFirstLine
15
- const lines = updateClause.content.split('\n')
16
- console.log(`Total lines: ${lines.length}`)
17
-
18
- let firstLine = ''
19
- for (const line of lines) {
20
- if (line.trim()) {
21
- firstLine = line
22
- break
23
- }
24
- }
25
-
26
- console.log(`First line: "${firstLine}"`)
27
- console.log('\n' + '='.repeat(70) + '\n')
28
-
29
- // 模拟 getClauseRestContent
30
- let firstLineIndex = 0
31
- for (let i = 0; i < lines.length; i++) {
32
- if (lines[i].trim()) {
33
- firstLineIndex = i
34
- break
35
- }
36
- }
37
-
38
- const restLines = lines.slice(firstLineIndex + 1)
39
- const restContent = restLines.join('\n')
40
-
41
- console.log(`Rest content (${restLines.length} lines):`)
42
- console.log(restContent)
43
- console.log('\n' + '='.repeat(70) + '\n')
44
-
45
- // 模拟 highlightSql on restContent
46
- console.log('Tokenizing rest content:')
47
- const tokens = tokenizeSql(restContent)
48
-
49
- tokens.slice(0, 15).forEach((token, idx) => {
50
- const value = token.value.replace(/\n/g, '\\n').replace(/ /g, '·')
51
- console.log(`${idx}. [${token.type.padEnd(12)}] "${value}"`)
52
- })
53
-
54
- console.log('\n' + '='.repeat(70) + '\n')
55
-
56
- // 模拟 highlightSql 的 whitespace 处理
57
- console.log('Highlighting (whitespace conversion):')
58
- const highlighted = tokens.slice(0, 6).map(token => {
59
- if (token.type === 'whitespace') {
60
- const converted = token.value.replace(/ /g, '&nbsp;').replace(/\n/g, '\n')
61
- console.log(` whitespace "${token.value.replace(/\n/g, '\\n').replace(/ /g, '·')}" => "${converted.replace(/\n/g, '\\n')}"`)
62
- return converted
63
- }
64
- const escaped = token.value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
65
- return `<span style="color: #xxx">${escaped}</span>`
66
- }).join('')
67
-
68
- console.log('\nHighlighted HTML (first 6 tokens):')
69
- console.log(highlighted.replace(/\n/g, '\\n'))
70
-
71
- // 检查是否有 &nbsp;&nbsp; 在开头
72
- if (highlighted.startsWith('&nbsp;&nbsp;')) {
73
- console.log('\n✅ SUCCESS: HTML starts with &nbsp;&nbsp; (2-space indent preserved)')
74
- } else {
75
- console.log('\n❌ ERROR: HTML does NOT start with &nbsp;&nbsp;')
76
- console.log(`First 50 chars: "${highlighted.substring(0, 50)}"`)
77
- }
@@ -1,29 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- // 简单的 SELECT 测试
4
- const simpleSelect = `SELECT id, username, email FROM users WHERE status = 'active';`
5
-
6
- console.log('=== Simple SELECT ===')
7
- console.log('Input:', simpleSelect)
8
- const formatted1 = formatSql(simpleSelect, { tabWidth: 2, keywordCase: 'upper' })
9
- console.log('Output:')
10
- console.log(formatted1)
11
- console.log('---')
12
- console.log('With escape codes:')
13
- console.log(JSON.stringify(formatted1))
14
-
15
- // 已格式化的 SELECT
16
- const preFormatted = `SELECT
17
- id,
18
- username,
19
- email
20
- FROM users;`
21
-
22
- console.log('\n=== Pre-formatted SELECT ===')
23
- console.log('Input:', preFormatted)
24
- const formatted2 = formatSql(preFormatted, { tabWidth: 2, keywordCase: 'upper' })
25
- console.log('Output:')
26
- console.log(formatted2)
27
- console.log('---')
28
- console.log('With escape codes:')
29
- console.log(JSON.stringify(formatted2))
@@ -1,51 +0,0 @@
1
- // Test SQL formatting with the complex query
2
- const input = `-- Complex query with subquery and window functions
3
- WITH user_stats AS ( SELECT u.id, u.username, COUNT(DISTINCT o.id) AS order_count, SUM(o.total_amount) AS total_spent, AVG(o.total_amount) AS avg_order_value, ROW_NUMBER() OVER ( ORDER BY SUM(o.total_amount) DESC ) AS spending_rank FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.created_at >= DATE_SUB (NOW (), INTERVAL 1 YEAR) GROUP BY u.id, u.username ) SELECT us.*, CASE WHEN us.spending_rank <= 10 THEN 'VIP' WHEN us.spending_rank <= 50 THEN 'Premium' ELSE 'Regular' END AS customer_tier FROM user_stats us WHERE us.order_count > 0 ORDER BY us.spending_rank;`;
4
-
5
- const expected = `-- Complex query with subquery and window functions
6
- WITH
7
- user_stats AS (
8
- SELECT
9
- u.id,
10
- u.username,
11
- COUNT(DISTINCT o.id) AS order_count,
12
- SUM(o.total_amount) AS total_spent,
13
- AVG(o.total_amount) AS avg_order_value,
14
- ROW_NUMBER() OVER (
15
- ORDER BY
16
- SUM(o.total_amount) DESC
17
- ) AS spending_rank
18
- FROM
19
- users u
20
- LEFT JOIN orders o ON u.id = o.user_id
21
- WHERE
22
- u.created_at >= DATE_SUB (NOW (), INTERVAL 1 YEAR)
23
- GROUP BY
24
- u.id,
25
- u.username
26
- )
27
- SELECT
28
- us.*,
29
- CASE
30
- WHEN us.spending_rank <= 10 THEN 'VIP'
31
- WHEN us.spending_rank <= 50 THEN 'Premium'
32
- ELSE 'Regular'
33
- END AS customer_tier
34
- FROM
35
- user_stats us
36
- WHERE
37
- us.order_count > 0
38
- ORDER BY
39
- us.spending_rank;`;
40
-
41
- console.log('Input SQL:');
42
- console.log(input);
43
- console.log('\n\nExpected Output:');
44
- console.log(expected);
45
- console.log('\n\nKey differences to implement:');
46
- console.log('1. WITH clause: CTE name should be on same line, subquery content indented 2 spaces');
47
- console.log('2. SELECT fields: each on separate line with 2 spaces indent');
48
- console.log('3. CASE WHEN: CASE on its own line, WHEN indented 2 spaces, END aligned with CASE');
49
- console.log('4. OVER clause: parentheses content should be on new lines with proper indent');
50
- console.log('5. FROM clause: table names and JOINs each on separate line with 2 spaces indent');
51
- console.log('6. JOIN: LEFT JOIN on separate line at same level as FROM table');
@@ -1,49 +0,0 @@
1
- import { tokenizeSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const sql = `UPDATE users
4
- SET
5
- status = 'inactive',
6
- updated_at = NOW ()`
7
-
8
- console.log('=== Testing tokenizeSql with indented SQL ===\n')
9
- console.log('Input SQL:')
10
- console.log(sql)
11
- console.log('\n' + '='.repeat(60) + '\n')
12
-
13
- const tokens = tokenizeSql(sql)
14
-
15
- console.log('Tokens:')
16
- tokens.forEach((token, idx) => {
17
- const value = token.value.replace(/\n/g, '\\n').replace(/ /g, '·')
18
- console.log(`${idx}. [${token.type.padEnd(12)}] "${value}"`)
19
- })
20
-
21
- console.log('\n' + '='.repeat(60) + '\n')
22
-
23
- // 检查第二行 SET 后的换行和缩进
24
- const setIdx = tokens.findIndex(t => t.type === 'keyword' && t.value.toUpperCase() === 'SET')
25
- if (setIdx !== -1 && setIdx + 1 < tokens.length) {
26
- console.log(`SET keyword found at token ${setIdx}`)
27
- console.log(`Next 3 tokens after SET:`)
28
- for (let i = 1; i <= 3 && setIdx + i < tokens.length; i++) {
29
- const t = tokens[setIdx + i]
30
- const v = t.value.replace(/\n/g, '\\n').replace(/ /g, '·')
31
- console.log(` ${setIdx + i}. [${t.type}] "${v}"`)
32
- }
33
-
34
- // 检查SET后面是否有换行+空格
35
- const nextToken = tokens[setIdx + 1]
36
- if (nextToken.type === 'whitespace') {
37
- const hasNewline = nextToken.value.includes('\n')
38
- const spaces = (nextToken.value.match(/\n(\s+)/) || [null, ''])[1]
39
- console.log(`\nWhitespace token after SET:`)
40
- console.log(` Has newline: ${hasNewline}`)
41
- console.log(` Spaces after newline: ${spaces.length} spaces`)
42
-
43
- if (spaces.length === 2) {
44
- console.log(' ✅ Correct! 2-space indentation preserved in token')
45
- } else if (spaces.length === 0) {
46
- console.log(' ❌ ERROR! No indentation in whitespace token')
47
- }
48
- }
49
- }
@@ -1,22 +0,0 @@
1
- const updateExample = `-- UPDATE statement with conditions\nUPDATE users\nSET \n status = 'inactive',\n updated_at = NOW(),\n last_login = NULL\nWHERE \n last_login < DATE_SUB(NOW(), INTERVAL 6 MONTH)\n AND status = 'active';`
2
-
3
- console.log('=== UPDATE Example Raw ===')
4
- console.log(updateExample)
5
- console.log('\n=== Character by character (first 100 chars) ===')
6
- for (let i = 0; i < Math.min(100, updateExample.length); i++) {
7
- const char = updateExample[i]
8
- if (char === '\n') {
9
- console.log(`[${i}]: \\n`)
10
- } else if (char === ' ') {
11
- console.log(`[${i}]: SPACE`)
12
- } else {
13
- console.log(`[${i}]: ${char}`)
14
- }
15
- }
16
-
17
- console.log('\n=== Lines ===')
18
- const lines = updateExample.split('\n')
19
- lines.forEach((line, idx) => {
20
- const spaces = line.length - line.trimStart().length
21
- console.log(`Line ${idx}: [${spaces} spaces] "${line}"`)
22
- })
@@ -1,45 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const inputSql = `-- UPDATE statement with conditions
4
- UPDATE users SET status = 'inactive', updated_at = NOW (), last_login = NULL WHERE last_login < DATE_SUB (NOW (), INTERVAL 6 MONTH) AND status = 'active';`
5
-
6
- const expectedOutput = `-- UPDATE statement with conditions
7
- UPDATE users
8
- SET
9
- status = 'inactive',
10
- updated_at = NOW (),
11
- last_login = NULL
12
- WHERE
13
- last_login < DATE_SUB (NOW (), INTERVAL 6 MONTH)
14
- AND status = 'active';`
15
-
16
- const result = formatSql(inputSql, { tabWidth: 2, keywordCase: 'upper' })
17
-
18
- console.log('=== 输入 SQL ===')
19
- console.log(inputSql)
20
- console.log('\n=== 当前格式化结果 ===')
21
- console.log(result)
22
- console.log('\n=== 期望结果 ===')
23
- console.log(expectedOutput)
24
- console.log('\n=== 对比 ===')
25
-
26
- const match = result.trim() === expectedOutput.trim()
27
- console.log('是否匹配:', match ? 'YES ✓' : 'NO ✗')
28
-
29
- if (!match) {
30
- console.log('\n=== 差异分析 ===')
31
- const resultLines = result.trim().split('\n')
32
- const expectedLines = expectedOutput.trim().split('\n')
33
- const maxLines = Math.max(resultLines.length, expectedLines.length)
34
-
35
- for (let i = 0; i < maxLines; i++) {
36
- const resultLine = resultLines[i] || '(missing)'
37
- const expectedLine = expectedLines[i] || '(missing)'
38
-
39
- if (resultLine !== expectedLine) {
40
- console.log(`Line ${i + 1} 不同:`)
41
- console.log(` 当前: "${resultLine}"`)
42
- console.log(` 期望: "${expectedLine}"`)
43
- }
44
- }
45
- }
@@ -1,56 +0,0 @@
1
- import { formatSql } from '../src/components/SqlFormat/parser.ts'
2
-
3
- const sql = "UPDATE users SET status = 'inactive', updated_at = NOW(), last_login = NULL WHERE last_login < DATE_SUB(NOW(), INTERVAL 6 MONTH) AND status = 'active';"
4
-
5
- console.log('=== Testing UPDATE Statement Indentation ===\n')
6
- console.log('Input SQL:')
7
- console.log(sql)
8
- console.log('\n' + '='.repeat(50) + '\n')
9
-
10
- const formatted = formatSql(sql, { tabWidth: 2, keywordCase: 'upper' })
11
- console.log('Formatted SQL:')
12
- console.log(formatted)
13
- console.log('\n' + '='.repeat(50) + '\n')
14
-
15
- // 检查每一行的缩进
16
- const lines = formatted.split('\n')
17
- lines.forEach((line, idx) => {
18
- const leadingSpaces = line.match(/^(\s*)/)?.[1].length || 0
19
- console.log(`Line ${idx + 1} (${leadingSpaces} spaces): "${line}"`)
20
- })
21
-
22
- console.log('\n' + '='.repeat(50) + '\n')
23
-
24
- // 验证期望的格式
25
- const expected = `-- UPDATE statement with conditions
26
- UPDATE users
27
- SET
28
- status = 'inactive',
29
- updated_at = NOW (),
30
- last_login = NULL
31
- WHERE
32
- last_login < DATE_SUB (NOW (), INTERVAL 6 MONTH)
33
- AND status = 'active';`
34
-
35
- console.log('Expected format:')
36
- console.log(expected)
37
-
38
- if (formatted.trim() === expected.trim()) {
39
- console.log('\n✅ YES ✓ match')
40
- } else {
41
- console.log('\n❌ NO ✗ mismatch')
42
- console.log('\nDifferences:')
43
- const formattedLines = formatted.split('\n')
44
- const expectedLines = expected.split('\n')
45
- const maxLines = Math.max(formattedLines.length, expectedLines.length)
46
-
47
- for (let i = 0; i < maxLines; i++) {
48
- const actualLine = formattedLines[i] || '(missing)'
49
- const expectedLine = expectedLines[i] || '(missing)'
50
- if (actualLine !== expectedLine) {
51
- console.log(`Line ${i + 1}:`)
52
- console.log(` Actual: "${actualLine}"`)
53
- console.log(` Expected: "${expectedLine}"`)
54
- }
55
- }
56
- }