395 lines
12 KiB
Swift
395 lines
12 KiB
Swift
import Foundation
|
|
import Testing
|
|
|
|
@testable import DataLiteCore
|
|
|
|
struct StringSQLTests {
|
|
// MARK: - Test Remove Single Line Comments
|
|
|
|
@Test func testSingleLineCommentAtStart() {
|
|
let input = """
|
|
-- This is a comment
|
|
SELECT * FROM users;
|
|
"""
|
|
let expected = """
|
|
|
|
SELECT * FROM users;
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testSingleLineCommentAfterStatement() {
|
|
let input = """
|
|
SELECT * FROM users; -- This is a comment
|
|
"""
|
|
let expected = """
|
|
SELECT * FROM users;\u{0020}
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testSingleLineCommentBetweenStatementLines() {
|
|
let input = """
|
|
INSERT INTO users (
|
|
id, name
|
|
-- comment between statement
|
|
) VALUES (1, 'Alice');
|
|
"""
|
|
let expected = """
|
|
INSERT INTO users (
|
|
id, name
|
|
|
|
) VALUES (1, 'Alice');
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testSingleLineCommentAtEnd() {
|
|
let input = """
|
|
SELECT * FROM users;
|
|
-- final comment
|
|
"""
|
|
let expected = """
|
|
SELECT * FROM users;
|
|
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testSingleLineCommentWithTabsAndSpaces() {
|
|
let input = "SELECT 1;\t -- comment with tab\nSELECT 2;"
|
|
let expected = "SELECT 1;\t \nSELECT 2;"
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testSingleLineCommentWithLiterals() {
|
|
let input = """
|
|
INSERT INTO logs (text) VALUES ('This isn''t -- a comment'); -- trailing comment
|
|
"""
|
|
let expected = """
|
|
INSERT INTO logs (text) VALUES ('This isn''t -- a comment');
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
// MARK: - Test Remove Multiline Comments
|
|
|
|
@Test func testMultilineCommentAtStart() {
|
|
let input = """
|
|
/* This is a
|
|
comment at the top */
|
|
SELECT * FROM users;
|
|
"""
|
|
let expected = """
|
|
|
|
SELECT * FROM users;
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentAtLineStart() {
|
|
let input = """
|
|
/* comment */ SELECT * FROM users;
|
|
"""
|
|
let expected = """
|
|
\u{0020}SELECT * FROM users;
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentInMiddleOfLine() {
|
|
let input = """
|
|
SELECT /* inline comment */ * FROM users;
|
|
"""
|
|
let expected = """
|
|
SELECT * FROM users;
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentAtEndOfLine() {
|
|
let input = """
|
|
SELECT * FROM users; /* trailing comment */
|
|
"""
|
|
let expected = """
|
|
SELECT * FROM users;\u{0020}
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentBetweenLines() {
|
|
let input = """
|
|
INSERT INTO users (
|
|
id,
|
|
/* this field stores username */
|
|
username,
|
|
email
|
|
) VALUES (1, 'alice', 'alice@example.com');
|
|
"""
|
|
let expected = """
|
|
INSERT INTO users (
|
|
id,
|
|
|
|
username,
|
|
email
|
|
) VALUES (1, 'alice', 'alice@example.com');
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentAtEndOfFile() {
|
|
let input = """
|
|
SELECT * FROM users;
|
|
/* final block comment */
|
|
"""
|
|
let expected = """
|
|
SELECT * FROM users;
|
|
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
@Test func testMultilineCommentWithLiterals() {
|
|
let input = """
|
|
INSERT INTO notes (text) VALUES ('This isn''t /* a comment */ either'); /* trailing comment */
|
|
"""
|
|
let expected = """
|
|
INSERT INTO notes (text) VALUES ('This isn''t /* a comment */ either');\u{0020}
|
|
"""
|
|
#expect(input.removingComments() == expected)
|
|
}
|
|
|
|
// MARK: - Test Trimming Lines
|
|
|
|
@Test func testTrimmingEmptyFirstLine() {
|
|
let input = "\nSELECT * FROM users;"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyFirstLineWithSpace() {
|
|
let input = " \nSELECT * FROM users;"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyFirstLineWithTab() {
|
|
let input = "\t\nSELECT * FROM users;"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyMiddleLine() {
|
|
let input = "SELECT *\n\nFROM users;"
|
|
let expected = "SELECT *\nFROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyMiddleLineWithSpace() {
|
|
let input = "SELECT *\n\u{0020}\nFROM users;"
|
|
let expected = "SELECT *\nFROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyMiddleLineWithTab() {
|
|
let input = "SELECT *\n\t\nFROM users;"
|
|
let expected = "SELECT *\nFROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyLastLine() {
|
|
let input = "SELECT * FROM users;\n"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyLastLineWithSpace() {
|
|
let input = "SELECT * FROM users; \n"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingEmptyLastLineWithTab() {
|
|
let input = "SELECT * FROM users;\t\n"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingTrailingSpacesOnly() {
|
|
let input = "SELECT * FROM users; "
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingTrailingSpacesAndNewline() {
|
|
let input = "SELECT * FROM users; \n"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingTrailingTabsOnly() {
|
|
let input = "SELECT * FROM users;\t\t"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingTrailingTabsAndNewline() {
|
|
let input = "SELECT * FROM users;\t\t\n"
|
|
let expected = "SELECT * FROM users;"
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingMultipleEmptyLinesAndSpaces() {
|
|
let input = "\n\n\t\u{0020}\nSELECT * FROM users;\n\n\u{0020}\n\n"
|
|
let expected = "SELECT * FROM users;"
|
|
print("zzzz\n\(input.trimmingLines())")
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingLiteralPreservesWhitespace() {
|
|
let input = "INSERT INTO logs VALUES ('line with\n\nspaces \t \n\n and tabs');"
|
|
let expected = input
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
@Test func testTrimmingPreserveLineBreaksInMultilineInsert() {
|
|
let input = """
|
|
INSERT INTO users (id, username, email)
|
|
VALUES \t
|
|
(1, 'john_doe', 'john@example.com'),
|
|
(2, 'jane_doe', 'jane@example.com');
|
|
"""
|
|
let expected = """
|
|
INSERT INTO users (id, username, email)
|
|
VALUES
|
|
(1, 'john_doe', 'john@example.com'),
|
|
(2, 'jane_doe', 'jane@example.com');
|
|
"""
|
|
#expect(input.trimmingLines() == expected)
|
|
}
|
|
|
|
// MARK: - Test Split Statements
|
|
|
|
@Test func testSplitSingleStatement() {
|
|
let input = "SELECT * FROM users;"
|
|
let expected = ["SELECT * FROM users"]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitSingleStatementWithoutSemicolon() {
|
|
let input = "SELECT * FROM users"
|
|
let expected = ["SELECT * FROM users"]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitMultipleStatements() {
|
|
let input = """
|
|
SELECT * FROM users;
|
|
DELETE FROM users WHERE id=123;
|
|
DELETE FROM users WHERE id=987;
|
|
"""
|
|
let expected = [
|
|
"SELECT * FROM users",
|
|
"DELETE FROM users WHERE id=123",
|
|
"DELETE FROM users WHERE id=987"
|
|
]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitMultipleStatementsLastWithoutSemicolon() {
|
|
let input = """
|
|
SELECT * FROM users;
|
|
DELETE FROM users WHERE id=1;
|
|
UPDATE users SET name='Bob' WHERE id=2
|
|
"""
|
|
let expected = [
|
|
"SELECT * FROM users",
|
|
"DELETE FROM users WHERE id=1",
|
|
"UPDATE users SET name='Bob' WHERE id=2"
|
|
]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitTextLiteralSemicolon() {
|
|
let input = "INSERT INTO logs (msg) VALUES ('Hello; world');"
|
|
let expected = ["INSERT INTO logs (msg) VALUES ('Hello; world')"]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitTextLiteralEscapingQuotes() {
|
|
let input = "INSERT INTO test VALUES ('It''s a test');"
|
|
let expected = ["INSERT INTO test VALUES ('It''s a test')"]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitMultipleSemicolon() {
|
|
let input = "SELECT * FROM users;;SELECT * FROM users;"
|
|
let expected = [
|
|
"SELECT * FROM users",
|
|
"SELECT * FROM users"
|
|
]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test(arguments: [
|
|
("BEGIN", "END"),
|
|
("Begin", "End"),
|
|
("begin", "end"),
|
|
("bEgIn", "eNd"),
|
|
("BeGiN", "EnD")
|
|
])
|
|
func testSplitWithBeginEnd(begin: String, end: String) {
|
|
let input = """
|
|
CREATE TABLE KDFMetadata (
|
|
id INTEGER PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|
|
CREATE TRIGGER KDFMetadataLimit
|
|
BEFORE INSERT ON KDFMetadata
|
|
WHEN (SELECT COUNT(*) FROM KDFMetadata) >= 1
|
|
\(begin)
|
|
SELECT RAISE(FAIL, 'Only one row allowed in KDFMetadata');
|
|
\(end);
|
|
"""
|
|
let expected = [
|
|
"""
|
|
CREATE TABLE KDFMetadata (
|
|
id INTEGER PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
)
|
|
""",
|
|
"""
|
|
CREATE TRIGGER KDFMetadataLimit
|
|
BEFORE INSERT ON KDFMetadata
|
|
WHEN (SELECT COUNT(*) FROM KDFMetadata) >= 1
|
|
\(begin)
|
|
SELECT RAISE(FAIL, 'Only one row allowed in KDFMetadata');
|
|
\(end)
|
|
"""
|
|
]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
|
|
@Test func testSplitWithSavepoints() {
|
|
let input = """
|
|
SAVEPOINT sp1;
|
|
INSERT INTO users (id, name) VALUES (1, 'Alice');
|
|
RELEASE SAVEPOINT sp1;
|
|
SAVEPOINT sp2;
|
|
UPDATE users SET name = 'Bob' WHERE id = 1;
|
|
ROLLBACK TO SAVEPOINT sp2;
|
|
RELEASE SAVEPOINT sp2;
|
|
"""
|
|
let expected = [
|
|
"SAVEPOINT sp1",
|
|
"INSERT INTO users (id, name) VALUES (1, 'Alice')",
|
|
"RELEASE SAVEPOINT sp1",
|
|
"SAVEPOINT sp2",
|
|
"UPDATE users SET name = 'Bob' WHERE id = 1",
|
|
"ROLLBACK TO SAVEPOINT sp2",
|
|
"RELEASE SAVEPOINT sp2"
|
|
]
|
|
#expect(input.splitStatements() == expected)
|
|
}
|
|
}
|