diff --git a/.github/.keep b/.github/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml index dca83b024..8c4fa1b7e 100644 --- a/.github/workflows/classroom.yml +++ b/.github/workflows/classroom.yml @@ -1,19 +1,220 @@ -name: GitHub Classroom Workflow - -on: - - push - - workflow_dispatch - +name: Autograding Tests +'on': +- push +- workflow_dispatch +- repository_dispatch permissions: checks: write actions: read contents: read - jobs: - build: - name: Autograding + run-autograding-tests: runs-on: ubuntu-latest if: github.actor != 'github-classroom[bot]' steps: - - uses: actions/checkout@v4 - - uses: education/autograding@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Step-1 Test + id: step-1-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-1 Test + setup-command: npm install + command: npm run test:1 + timeout: 10 + max-score: 10 + - name: Step-2 Test + id: step-2-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-2 Test + setup-command: npm install + command: npm run test:2 + timeout: 10 + max-score: 10 + - name: Step-3 Test + id: step-3-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-3 Test + setup-command: npm install + command: npm run test:3 + timeout: 10 + max-score: 10 + - name: Step-4 Test + id: step-4-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-4 Test + setup-command: npm install + command: npm run test:4 + timeout: 10 + - name: Step-5 Test + id: step-5-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-5 Test + setup-command: npm install + command: npm run test:5 + timeout: 10 + max-score: 10 + - name: Step-6 Test + id: step-6-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-6 Test + setup-command: npm install + command: npm run test:6 + timeout: 10 + max-score: 10 + - name: Step-7 Test + id: step-7-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-7 Test + setup-command: npm install + command: npm run test:7 + timeout: 10 + max-score: 10 + - name: Step-8 Test + id: step-8-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-8 Test + setup-command: npm install + command: npm run test:8 + timeout: 10 + max-score: 10 + - name: Step-9 Test + id: step-9-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-9 Test + setup-command: npm install + command: npm run test:9 + timeout: 10 + max-score: 10 + - name: Step-10 Test + id: step-10-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-10 Test + setup-command: npm install + command: npm run test:10 + timeout: 10 + max-score: 10 + - name: Step-11 Test + id: step-11-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-11 Test + setup-command: npm install + command: npm run test:11 + timeout: 10 + max-score: 10 + - name: Step-12 Test + id: step-12-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-12 Test + setup-command: npm install + command: npm run test:12 + timeout: 10 + max-score: 10 + - name: Step-13 Test + id: step-13-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-13 Test + setup-command: npm install + command: npm run test:13 + timeout: 10 + max-score: 10 + - name: Step-14 Test + id: step-14-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-14 Test + setup-command: npm install + command: npm run test:14 + timeout: 10 + max-score: 10 + - name: Step-15 Test + id: step-15-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-15 Test + setup-command: npm install + command: npm run test:15 + timeout: 10 + max-score: 10 + - name: Step-16 Test + id: step-16-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-16 Test + setup-command: npm install + command: npm run test:16 + timeout: 10 + max-score: 10 + - name: Step-17 Test + id: step-17-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-17 Test + setup-command: npm install + command: npm run test:17 + timeout: 10 + max-score: 10 + - name: Step-18 Test + id: step-18-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-18 Test + setup-command: npm install + command: npm run test:18 + timeout: 10 + max-score: 10 + - name: Step-19 Test + id: step-19-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-19 Test + setup-command: npm install + command: npm run test:19 + timeout: 10 + max-score: 10 + - name: Step-20 Test + id: step-20-test + uses: education/autograding-command-grader@v1 + with: + test-name: Step-20 Test + setup-command: npm install + command: npm run test:20 + timeout: 10 + max-score: 10 + - name: Autograding Reporter + uses: education/autograding-grading-reporter@v1 + env: + STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}" + STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}" + STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}" + STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}" + STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}" + STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}" + STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}" + STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}" + STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}" + STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}" + STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}" + STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}" + STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}" + STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}" + STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}" + STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}" + STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}" + STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}" + STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}" + STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}" + with: + runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..b242572ef --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/123456 b/123456 new file mode 100644 index 000000000..e7655ef77 --- /dev/null +++ b/123456 @@ -0,0 +1,39 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAZP6S+8K +NL3wxyrHBgpBvYAAAAEAAAAAEAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQDCu6d/avQP +JIc/fWZaYqfe4NvuCKUiB7cFemTFu0M0oXfOf1vpOMLT3fMNYVR4mXbret9DgveS6fsCa9 +hP4M2ss17GY0pO0MZAxqMMIXD75biTDmG1YqKIc+zf95YDcrJkG9mhCb9P8Glm9EwQqfT5 +cs8H+QtFWrZBWGtougfJ014naDCaoFg0b+WgwLdJjG+Omtl99gjpWrD3Akhx9ucGNA2ADe +IM5bX1dTtDVahAJnIjb6jgUA55FSe7TdIFshoZYZxtH5SzC9zfHlI50HCd8Wq520it0jjY +N1y+Ws3n277dyQCxjy3YrrYzyP6GSCj1zCAIdzhpd8tjTasHzY1hFWIjZKEItwSnAXCGoT +6u5olmLI65ubEGrZUMGbk7xK8r9C/DtGFHPSCVAHFkSJB2ew+XzPJIr0KyKErLNCjWWaQb +xmn0oIYkSrmfIRFZgnbjMBAjz3skK3A5iHD0MFrSQo8xnOimEs5Etd16HWjqAvUViCr766 +xJDrMgixpgjYUAAAWQV8jfZ5SqpVWZG+ursMd65UYX9Q009v73AAFgJDUAemB9prCReqXt +yypxbF7uXsYEtiN9gytsMlYJtXEbfbNHAlrXmwwbvo//RsCqagEHEryyxx2vUQ3PeyB52M +omj9Whkh3cWz2ioYCzBqPRO88HZ+plWgFSqsXgsJpHjKRZbvXZPt3XztxWL93zxt8gceUX +JPWcyhHP4L0vOQyEdt1hqGX/ePTyrKAlj7yXu5cUIe6doxzMso7FimCU4Fjl90JIUKcx5e +B/vYU6QC2wbf2nUtf7L8FcfEGSsvOzAyNSaBWDy4Evlqe8vHXMXMuVtIggYzMyY69vLG/2 +sJ4YJUA+rLVqqdv8Ek6m6j3XfNK/M+qkvz5nxa3kIsJKU/dC868wa9sL3TGmzyz2Xyr8wG +cmKDcinrblIkTrSEQxLZ97/QehF2AlBl7E1SpmEiR1E2D412lN1+CT0wXIRCQCkubpYCcp +tr8ivVuJxXjqgm3th0WmmE2PcZxa+iKKbiVubbDIMZ1nPfTSuX8VOqW/wx8Cu+hFRx0o6i +KAlGKbNVcvLltvmp9DInCvb+N3iArKkFVNTebmBnHEEJM/pj/70JNVsOs/Lf5ixxpu+H91 +eGZOhUOd0+cn+bFTC2LZCaU7Dajmc9x1meU3WHCEyJZ74gquGHkMVaKI4qdDIWYhor/5Wz +dRAFVkOp3ogfrB15X27CBMAvbMXEAyRItReYUPcoru6jQknhJ1ez5AxN4iXhHKZo+lI1Uu +8LAYmm4/hVWoSSZXxFzJ6F8N/MGDSn1mXzytIZDkNxmQkMfvt8pIS7Dw6q95oM48Bmc+Df +BJHiMxS6DR3+ScuJK7AVt/pVrhjFxyOHyGw5gZPe34ovhxnmLNYbSc3jcALUpuB2ldSscC +vsKzU9tVk52qMNXLnh+KRb5QHg5led91CH+2ehDzj6NKOJ4gXdP4B/1tTX4S5Jy8t+tO3K +vXlDZgbXpAX4dGCp4ufbyB+d830SfiGhg//kdvys7/e95xdp8Gq1KC6+8tpeW7MPj/bgxS +6kwZO/whxM5L7I0BYHZ8FshC1Yp2rToHHMTKTZb0XMHxKl4uUDAoc07VJ0QPGQprwPmm9E +QSajOnh8+AT2djqfHNKCT6hz090SnaSW1VxeJPW59OxhAXThDdPa6xqzq5FImaXlN4dY/b +tAZhuIaKLBDGetGneX9kXVH3Zf3cNYwRGO6gHkVs81w9xH80o0shoO9fCUUbayhXqpvOJx +obHrf71qOsZ5bK6M2YwDrg0F/gEle/EXGmx4awJ0PjlnL5gcNBXEEqS9obDp1J9eHhfG18 +SL75sWYvOKJ2hPcQkAS0aUuLcc4NQ8MyTkiRxOiwD63lqVaFn2kWV/mKvMYx9MjEevLIBn +uO+gCWH+zLtoK1jruwVDHaZorobS+eaCQjjzNhk/5uWswCoJJy0NbfykVwMvjghGcMAr91 +wkxmu+cCarlR6EpHKIsE9znoin83IbSANi22tqDV4NcFIggWClBLIB+Z1wqaBiqCy0exww +W4/+GlZ3ibIOarpEG7BD1m5GfQ4+0mz/P3rz9ILMH3sHMw70NtS41TMxDKg8t+rbu7queq +QoJUjdkYbiGdnafCgrcCmae4YWlaPxlkIPDcYD3zKAFJXXNVnGLXXyH6gYrjBv3ejQ5gne +bHK4sS9RBUpLBaJqGFCQ5iKANT6Zn3omVM0DCSh2QQPKZlIuMXeYFdR4pUnIAv0SAcyJCd +/ntThB+Fp8tANHTPEJPNAQxPEc86l8TexuwNl5SNa0/5STiMsYb9Q9baTJbaWnWS/0vTYl +kyPGYk0JCP/4DlexJLUrty51/RYxrqdDedaIcK17nJ5TWW9AA2kqVdyzbEW43f61csbhqh +mCiQsu2pMinkI50Wbtd6e4ut8nE= +-----END OPENSSH PRIVATE KEY----- diff --git a/123456.pub b/123456.pub new file mode 100644 index 000000000..961268c09 --- /dev/null +++ b/123456.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCu6d/avQPJIc/fWZaYqfe4NvuCKUiB7cFemTFu0M0oXfOf1vpOMLT3fMNYVR4mXbret9DgveS6fsCa9hP4M2ss17GY0pO0MZAxqMMIXD75biTDmG1YqKIc+zf95YDcrJkG9mhCb9P8Glm9EwQqfT5cs8H+QtFWrZBWGtougfJ014naDCaoFg0b+WgwLdJjG+Omtl99gjpWrD3Akhx9ucGNA2ADeIM5bX1dTtDVahAJnIjb6jgUA55FSe7TdIFshoZYZxtH5SzC9zfHlI50HCd8Wq520it0jjYN1y+Ws3n277dyQCxjy3YrrYzyP6GSCj1zCAIdzhpd8tjTasHzY1hFWIjZKEItwSnAXCGoT6u5olmLI65ubEGrZUMGbk7xK8r9C/DtGFHPSCVAHFkSJB2ew+XzPJIr0KyKErLNCjWWaQbxmn0oIYkSrmfIRFZgnbjMBAjz3skK3A5iHD0MFrSQo8xnOimEs5Etd16HWjqAvUViCr766xJDrMgixpgjYU= dell@DESKTOP-6A4KT9B diff --git a/README.md b/README.md index eadfc715a..c8a05be53 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A SQL database engine written in JavaScript [![GitHub Repo](https://img.shields.io/github/stars/ChakshuGautam/stylusdb-sql?style=social)](https://github.com/ChakshuGautam/stylusdb-sql)

+ This is the base repository for cohort members to follow the tutorial and send in their own StylusDB SQL implementations. You can refer to a complete implementation @ [ChakshuGautam/stylusdb-sql](https://github.com/ChakshuGautam/stylusdb-sql). Follow the steps given in the documentation to create your own implementation and make those tests pass. diff --git a/enrollment.csv b/enrollment.csv new file mode 100644 index 000000000..e80af8d93 --- /dev/null +++ b/enrollment.csv @@ -0,0 +1,6 @@ +student_id,course +1,Mathematics +1,Physics +2,Chemistry +3,Mathematics +5,Biology \ No newline at end of file diff --git a/h origin main b/h origin main new file mode 100644 index 000000000..043bc8cba --- /dev/null +++ b/h origin main @@ -0,0 +1,77 @@ +commit c6c4722462f58b87ec561b44f722b87394449879 (HEAD -> main, origin/main) +Author: PayalKumari10 +Date: Tue Apr 23 23:53:02 2024 +0530 + + solve 2 + +commit 157da9379d2616223f6f2c73244e229e67b34ac4 +Author: Payal +Date: Tue Apr 23 12:45:01 2024 +0530 + + feat: steps 2 and 3 + +commit 8ccd37d636ac3b16a7302f3cb49b1cd0371826d8 +Author: Payal +Date: Wed Apr 10 15:39:26 2024 +0530 + + feat: step-1 + +commit c0d72b2242c7618eaa8ab74afb1947d674ab68a8 +Author: Payal +Date: Tue Apr 9 17:02:01 2024 +0530 + + feat: step2 + +commit 6744606076df585ed75fb999baea3dfc8eef0ce0 +Author: Payal +Date: Tue Apr 9 00:10:43 2024 +0530 + + feat: steps 2 and 3 + +commit d888539ed59be6106c0b3e2ca06d7723202b2773 +Author: Payal +Date: Mon Apr 8 23:30:55 2024 +0530 + + feat: steps 2 and 3 + +commit 8a128579d871138933c2f2becf418d959eb7a243 (upstream/main) +Author: Yash Mittal +Date: Sun Mar 3 16:31:41 2024 +0530 + + [skip ci] feat: add .github + +commit 21de1ee5c96d6b959ac2e6d30d7cd738cce3e416 +Author: Yash Mittal +Date: Sun Mar 3 16:26:09 2024 +0530 + + fix: import paths in tests + +commit a90f157bb71f267646b7f8da6fce0f3a99a3465c +Author: Yash Mittal +Date: Sun Mar 3 15:41:16 2024 +0530 + + docs: update README with StylusDB-SQL base repo logo + +commit a5c39856bb3ceb290dda645c620b66b056776b5f +Author: Yash Mittal +Date: Sun Mar 3 15:37:36 2024 +0530 + + fix: fix step wise test regex + +commit efac4ad2e515b6a4868c04de08de4fac3f86f90f +Author: Yash Mittal +Date: Sun Mar 3 14:23:56 2024 +0530 + + feat: add stepwise test folders + +commit ce7a629663ee9f414930ad070bc7437074ecd1e4 (upstream/test) +Author: Yash Mittal +Date: Sat Mar 2 13:40:58 2024 +0530 + + feat: add tests + +commit 0dfdcdad918de949f81aec9f76cc367bb8bf3712 +Author: Yash Mittal +Date: Sat Mar 2 13:29:23 2024 +0530 + + feat: push docs diff --git a/package-lock.json b/package-lock.json index 3afaec37f..a6ba782df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.1.6", "license": "ISC", "dependencies": { - "csv-parser": "^3.0.0", "json2csv": "^6.0.0-alpha.2", "xterm": "^5.3.0" }, @@ -17,6 +16,7 @@ "stylusdb-cli": "node ./src/cli.js" }, "devDependencies": { + "csv-parser": "^3.0.0", "jest": "^29.7.0" } }, @@ -1573,6 +1573,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz", "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==", + "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -2943,6 +2944,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } diff --git a/package.json b/package.json index f52103d5c..d2b9c2349 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "A minimal SQL based DB based on CSV files. For educational purposes only.", "main": "./src/index.js", "directories": { - "doc": "docs" + "doc": "docs", + "test": "tests" }, "scripts": { "test": "jest", @@ -38,11 +39,11 @@ "author": "Chakshu Gautam", "license": "ISC", "devDependencies": { + "csv-parser": "^3.0.0", "jest": "^29.7.0" }, "dependencies": { - "csv-parser": "^3.0.0", "json2csv": "^6.0.0-alpha.2", "xterm": "^5.3.0" } -} \ No newline at end of file +} diff --git a/sample.csv b/sample.csv new file mode 100644 index 000000000..448653236 --- /dev/null +++ b/sample.csv @@ -0,0 +1,4 @@ +id,name,age +1,John,30 +2,Jane,25 +3,Bob,22 diff --git a/src/cli.js b/src/cli.js new file mode 100644 index 000000000..7798fd1a9 --- /dev/null +++ b/src/cli.js @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +const readline = require("readline"); +const { executeSELECTQuery, executeINSERTQuery,executeDELETEQuery,} = require("./index"); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +rl.setPrompt("SQL> "); +console.log( + 'SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.' +); + +rl.prompt(); + +rl.on("line", async (line) => { + if (line.toLowerCase() === "exit") { + rl.close(); + return; + } + + try { + if (line.toLowerCase().startsWith("select")) { + const result = await executeSELECTQuery(line); + console.log("Result:", result); + } else if (line.toLowerCase().startsWith("insert into")) { + const result = await executeINSERTQuery(line); + console.log(result.message); + } else if (line.toLowerCase().startsWith("delete from")) { + const result = await executeDELETEQuery(line); + console.log(result.message); + } else { + console.log("Unsupported command"); + } + } catch (error) { + console.error("Error:", error.message); + } + + rl.prompt(); +}).on("close", () => { + console.log("Exiting SQL CLI"); + process.exit(0); +}); \ No newline at end of file diff --git a/src/csvReader.js b/src/csvReader.js index e69de29bb..c880992bb 100644 --- a/src/csvReader.js +++ b/src/csvReader.js @@ -0,0 +1,33 @@ +const fs = require("fs"); +const csv = require("csv-parser"); +const { parse } = require("json2csv"); + +async function readCSV(filePath) { + return new Promise((resolve, reject) => { + const data = []; + fs.createReadStream(filePath) + .pipe(csv()) + .on('data', (row) => { + data.push(row); + }) + .on('end', () => { + resolve(data); + }) + .on('error', (error) => { + reject(error); + }); + }); +} + +async function writeCSV(filename, data) { + try { + const csvData = parse(data); + fs.writeFileSync(filename, csvData); + } catch (error) { + throw error; + } +} +module.exports = { readCSV, writeCSV }; + + + diff --git a/src/queryExecutor.js b/src/queryExecutor.js new file mode 100644 index 000000000..122de42c0 --- /dev/null +++ b/src/queryExecutor.js @@ -0,0 +1,390 @@ +// src/index.js +const { parseSelectQuery,parseInsertQuery, parseDeleteQuery } = require('./queryParser'); +const { readCSV, writeCSV }= require('./csvReader'); + + +// Helper functions for different JOIN types +function performInnerJoin(data, joinData, joinCondition, fields, table) { + return data.flatMap(mainRow => { + return joinData + .filter(joinRow => { + const mainValue = mainRow[joinCondition.left.split('.')[1]]; + const joinValue = joinRow[joinCondition.right.split('.')[1]]; + return mainValue === joinValue; + }) + .map(joinRow => { + return fields.reduce((acc, field) => { + const [tableName, fieldName] = field.split('.'); + acc[field] = tableName === table ? mainRow[fieldName] : joinRow[fieldName]; + return acc; + }, {}); + }); + }); +} + +function performRightJoin(data, joinData, joinCondition, fields, table) { + // Cache the structure of a main table row (keys only) + const mainTableRowStructure = + data.length > 0 + ? Object.keys(data[0]).reduce((acc, key) => { + acc[key] = null; // Set all values to null initially + return acc; + }, {}) + : {}; + + return joinData.map((joinRow) => { + const mainRowMatch = data.find((mainRow) => { + const mainValue = getValueFromRow(mainRow, joinCondition.left); + const joinValue = getValueFromRow(joinRow, joinCondition.right); + return mainValue === joinValue; + }); + + // Use the cached structure if no match is found + const mainRowToUse = mainRowMatch || mainTableRowStructure; + + // Include all necessary fields from the 'student' table + return createResultRow(mainRowToUse, joinRow, fields, table, true); + }); + } + + +function performLeftJoin(data, joinData, joinCondition, fields, table) { + return data.flatMap(mainRow => { + const matchingJoinRows = joinData.filter(joinRow => { + const mainValue = getValueFromRow(mainRow, joinCondition.left); + const joinValue = getValueFromRow(joinRow, joinCondition.right); + return mainValue === joinValue; + }); + + if (matchingJoinRows.length === 0) { + return [createResultRow(mainRow, null, fields, table, true)]; + } + + return matchingJoinRows.map(joinRow => createResultRow(mainRow, joinRow, fields, table, true)); + }); +} + +function getValueFromRow(row, compoundFieldName) { + const [tableName, fieldName] = compoundFieldName.split('.'); + return row[`${tableName}.${fieldName}`] || row[fieldName]; +} + + +function createResultRow(mainRow, joinRow, fields, table, includeAllMainFields) { + const resultRow = {}; + + if (includeAllMainFields) { + // Include all fields from the main table + Object.keys(mainRow || {}).forEach(key => { + const prefixedKey = `${table}.${key}`; + resultRow[prefixedKey] = mainRow ? mainRow[key] : null; + }); + } + + // Now, add or overwrite with the fields specified in the query + fields.forEach(field => { + const [tableName, fieldName] = field.includes('.') ? field.split('.') : [table, field]; + resultRow[field] = tableName === table && mainRow ? mainRow[fieldName] : joinRow ? joinRow[fieldName] : null; + }); + + return resultRow; +} + + +function evaluateCondition(row, clause) { + let { field, operator, value } = clause; + + // Check if the field exists in the row + if (row[field] === undefined) { + throw new Error(`Invalid field: ${field}`); + } + + // Parse row value and condition value based on their actual types + const rowValue = parseValue(row[field]); + let conditionValue = parseValue(value); + + if (operator === 'LIKE') { + // Transform SQL LIKE pattern to JavaScript RegExp pattern + const regexPattern = '^' + value.replace(/%/g, '.*').replace(/_/g, '.') + '$'; + const regex = new RegExp(regexPattern, 'i'); // 'i' for case-insensitive matching + return (regex.test(row[field])); + } + + switch (operator) { + case '=': + return rowValue === conditionValue; + case '<': + return rowValue < conditionValue; + case '>=': + return rowValue >= conditionValue; + case '<=': + return rowValue <= conditionValue; + case '!=': + return rowValue !== conditionValue; + case '>': + return rowValue > conditionValue; + + default: + throw new Error(`Unsupported operator: ${operator}`); + } +} + + // Helper function to parse value based on its apparent type + function parseValue(value) { + + // Return null or undefined as is + if (value === null || value === undefined) { + return value; + } + + // If the value is a string enclosed in single or double quotes, remove them + if (typeof value === 'string' && ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"')))) { + value = value.substring(1, value.length - 1); + } + + // Check if value is a number + if (!isNaN(value) && value.trim() !== '') { + return Number(value); + } + // Assume value is a string if not a number + return value; +} + +function applyGroupBy(data, groupByFields, aggregateFunctions) { + const groupResults = {}; + + data.forEach(row => { + // Generate a key for the group + const groupKey = groupByFields.map(field => row[field]).join('-'); + + // Initialize group in results if it doesn't exist + if (!groupResults[groupKey]) { + groupResults[groupKey] = { count: 0, sums: {}, mins: {}, maxes: {} }; + groupByFields.forEach(field => groupResults[groupKey][field] = row[field]); + } + + // Aggregate calculations + groupResults[groupKey].count += 1; + aggregateFunctions.forEach(func => { + const match = /(\w+)\((\w+)\)/.exec(func); + if (match) { + const [, aggFunc, aggField] = match; + const value = parseFloat(row[aggField]); + + switch (aggFunc.toUpperCase()) { + case 'SUM': + groupResults[groupKey].sums[aggField] = (groupResults[groupKey].sums[aggField] || 0) + value; + break; + case 'MIN': + groupResults[groupKey].mins[aggField] = Math.min(groupResults[groupKey].mins[aggField] || value, value); + break; + case 'MAX': + groupResults[groupKey].maxes[aggField] = Math.max(groupResults[groupKey].maxes[aggField] || value, value); + break; + // Additional aggregate functions can be added here + } + } + }); + }); + + // Convert grouped results into an array format + return Object.values(groupResults).map(group => { + // Construct the final grouped object based on required fields + const finalGroup = {}; + groupByFields.forEach(field => finalGroup[field] = group[field]); + aggregateFunctions.forEach(func => { + const match = /(\w+)\((\*|\w+)\)/.exec(func); + if (match) { + const [, aggFunc, aggField] = match; + switch (aggFunc.toUpperCase()) { + case 'MIN': + finalGroup[func] = group.mins[aggField]; + break; + case 'MAX': + finalGroup[func] = group.maxes[aggField]; + break; + case 'COUNT': + finalGroup[func] = group.count; + break; + case 'SUM': + finalGroup[func] = group.sums[aggField]; + break; + + // Additional aggregate functions can be handled here + } + } + }); + + return (finalGroup); + }); +} + +async function executeSELECTQuery(query) { + try { + + const { fields, table, whereClauses, joinType, joinTable, joinCondition, groupByFields, hasAggregateWithoutGroupBy, orderByFields, limit, isDistinct } = parseSelectQuery(query); + let data = await readCSV(`${table}.csv`); + + if (joinTable && joinCondition) { + const joinData = await readCSV(`${joinTable}.csv`); + switch (joinType.toUpperCase()) { + case 'INNER': + data = performInnerJoin(data, joinData, joinCondition, fields, table); + break; + case 'RIGHT': + data = performRightJoin(data, joinData, joinCondition, fields, table); + break; + case 'LEFT': + data = performLeftJoin(data, joinData, joinCondition, fields, table); + break; + // Handle default case or unsupported JOIN types + default: + throw new Error(`Unsupported JOIN type: ${joinType}`); + } + } + // Apply WHERE clause filtering after JOIN (or on the original data if no join) + let filteredData = whereClauses.length > 0 + ? data.filter(row => whereClauses.every(clause => evaluateCondition(row, clause))) + : data; + + let groupResults = filteredData; + if (hasAggregateWithoutGroupBy) { + // Special handling for queries like 'SELECT COUNT(*) FROM table' + const result = {}; + + fields.forEach(field => { + const match = /(\w+)\((\*|\w+)\)/.exec(field); + if (match) { + const [, aggFunc, aggField] = match; + switch (aggFunc.toUpperCase()) { + case "COUNT": + result[field] = filteredData.length; + break; + case 'SUM': + result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0); + break; + case 'AVG': + result[field] = filteredData.reduce((acc, row) => acc + parseFloat(row[aggField]), 0) / filteredData.length; + break; + case 'MIN': + result[field] = Math.min(...filteredData.map(row => parseFloat(row[aggField]))); + break; + case 'MAX': + result[field] = Math.max(...filteredData.map(row => parseFloat(row[aggField]))); + break; + // Additional aggregate functions can be handled here + } + } + }); + + return [result]; + // Add more cases here if needed for other aggregates + } else if (groupByFields) { + groupResults = applyGroupBy(filteredData, groupByFields, fields); + + // Order them by the specified fields + let orderedResults = groupResults; + if (orderByFields) { + orderedResults = groupResults.sort((a, b) => { + for (let { fieldName, order } of orderByFields) { + if (a[fieldName] < b[fieldName]) return order === "ASC" ? -1 : 1; + if (a[fieldName] > b[fieldName]) return order === "ASC" ? 1 : -1; + } + return 0; + }); + } + if (limit !== null) { + groupResults = groupResults.slice(0, limit); + } + return groupResults; + } else { + // Order them by the specified fields + let orderedResults = groupResults; + if (orderByFields) { + orderedResults = groupResults.sort((a, b) => { + for (let { fieldName, order } of orderByFields) { + if (a[fieldName] < b[fieldName]) return order === "ASC" ? -1 : 1; + if (a[fieldName] > b[fieldName]) return order === "ASC" ? 1 : -1; + } + return 0; + }); + } + + // Select the specified fields + let finalResults = orderedResults.map(row => { + const selectedRow = {}; + fields.forEach(field => { + // Assuming 'field' is just the column name without table prefix + selectedRow[field] = row[field]; + }); + return selectedRow; + }); + + // Remove duplicates if specified + let distinctResults = finalResults; + if (isDistinct) { + distinctResults = [...new Map(finalResults.map(item => [fields.map(field => item[field]).join('|'), item])).values()]; + } + + let limitResults = distinctResults; + if (limit !== null) { + limitResults = distinctResults.slice(0, limit); + } + + return limitResults; + + + } + } catch (error) { + throw new Error(`Error executing query: ${error.message}`); + } + } + + + async function executeINSERTQuery(query) { + console.log(parseInsertQuery(query)); + const { table, columns, values } = parseInsertQuery(query); + const data = await readCSV(`${table}.csv`); + + // Create a new row object + const newRow = {}; + columns.forEach((column, index) => { + // Remove single quotes from the values + let value = values[index]; + if (value.startsWith("'") && value.endsWith("'")) { + value = value.substring(1, value.length - 1); + } + newRow[column] = value; + }); + + // Add the new row to the data + data.push(newRow); + + // Save the updated data back to the CSV file + await writeCSV(`${table}.csv`, data); // Implement writeCSV function + + return { message: "Row inserted successfully." }; + } + + async function executeDELETEQuery(query) { + const { table, whereClauses } = parseDeleteQuery(query); + let data = await readCSV(`${table}.csv`); + + if (whereClauses.length > 0) { + // Filter out the rows that meet the where clause conditions + data = data.filter( + (row) => !whereClauses.every((clause) => evaluateCondition(row, clause)) + ); + } else { + // If no where clause, clear the entire table + data = []; + } + + // Save the updated data back to the CSV file + await writeCSV(`${table}.csv`, data); + + return { message: "Rows deleted successfully." }; + } + + + module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery } \ No newline at end of file diff --git a/src/queryParser.js b/src/queryParser.js new file mode 100644 index 000000000..2d3fdab85 --- /dev/null +++ b/src/queryParser.js @@ -0,0 +1,186 @@ +function parseSelectQuery(query) { + try { + // Trim the query to remove any leading/trailing whitespaces + query = query.trim(); + + // Initialize distinct flag + let isDistinct = false; + + // Check for DISTINCT keyword and update the query + if (query.toUpperCase().includes('SELECT DISTINCT')) { + isDistinct = true; + query = query.replace('SELECT DISTINCT', 'SELECT'); + } + + // Updated regex to capture LIMIT clause and remove it for further processing + const limitRegex = /\sLIMIT\s(\d+)/i; + const limitMatch = query.match(limitRegex); + + let limit = null; + if (limitMatch) { + limit = parseInt(limitMatch[1], 10); + query = query.replace(limitRegex, ''); // Remove LIMIT clause + } + + // Process ORDER BY clause and remove it for further processing + const orderByRegex = /\sORDER BY\s(.+)/i; + const orderByMatch = query.match(orderByRegex); + let orderByFields = null; + if (orderByMatch) { + orderByFields = orderByMatch[1].split(',').map(field => { + const [fieldName, order] = field.trim().split(/\s+/); + return { fieldName, order: order ? order.toUpperCase() : 'ASC' }; + }); + query = query.replace(orderByRegex, ''); + } + + // Process GROUP BY clause and remove it for further processing + const groupByRegex = /\sGROUP BY\s(.+)/i; + const groupByMatch = query.match(groupByRegex); + let groupByFields = null; + if (groupByMatch) { + groupByFields = groupByMatch[1].split(',').map(field => field.trim()); + query = query.replace(groupByRegex, ''); + } + + // Process WHERE clause + const whereSplit = query.split(/\sWHERE\s/i); + const queryWithoutWhere = whereSplit[0]; // Everything before WHERE clause + const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null; + + // Process JOIN clause + const joinSplit = queryWithoutWhere.split(/\s(INNER|LEFT|RIGHT) JOIN\s/i); + const selectPart = joinSplit[0].trim(); // Everything before JOIN clause + + // Extract JOIN information + const { joinType, joinTable, joinCondition } = parseJoinClause(queryWithoutWhere); + + // Parse SELECT part + const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i; + const selectMatch = selectPart.match(selectRegex); + if (!selectMatch) { + throw new Error('Invalid SELECT format'); + } + const [, fields, table] = selectMatch; + + // Parse WHERE part if it exists + let whereClauses = []; + if (whereClause) { + whereClauses = parseWhereClause(whereClause); + } + + // Check for aggregate functions without GROUP BY + const hasAggregateWithoutGroupBy = checkAggregateWithoutGroupBy(query, groupByFields); + + return { + fields: fields.split(',').map(field => field.trim()), + table: table.trim(), + whereClauses, + joinType, + joinTable, + joinCondition, + groupByFields, + orderByFields, + hasAggregateWithoutGroupBy, + limit, + isDistinct + }; + } catch (error) { + throw new Error(`Query parsing error: ${error.message}`); + } +} + +function checkAggregateWithoutGroupBy(query, groupByFields) { + const aggregateFunctionRegex = /(\bCOUNT\b|\bAVG\b|\bSUM\b|\bMIN\b|\bMAX\b)\s*\(\s*(\*|\w+)\s*\)/i; + return aggregateFunctionRegex.test(query) && !groupByFields; +} + +function parseJoinClause(query) { + const joinRegex = /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i; + const joinMatch = query.match(joinRegex); + + if (joinMatch) { + return { + joinType: joinMatch[1].trim(), + joinTable: joinMatch[2].trim(), + joinCondition: { + left: joinMatch[3].trim(), + right: joinMatch[4].trim() + } + }; + } + + return { + joinType: null, + joinTable: null, + joinCondition: null + }; +} + + +function parseWhereClause(whereString) { + const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/; + return whereString.split(/ AND | OR /i).map(conditionString => { + if (conditionString.includes(' LIKE ')) { + const [field, pattern] = conditionString.split(/\sLIKE\s/i); + return { field: field.trim(), operator: 'LIKE', value: pattern.trim().replace(/^'(.*)'$/, '$1') }; + } else { + const match = conditionString.match(conditionRegex); + if (match) { + const [, field, operator, value] = match; + return { field: field.trim(), operator, value: value.trim() }; + } + throw new Error('Invalid WHERE clause format'); + } + }); +} + + +function parseInsertQuery(query) { + const insertRegex = /INSERT INTO (\w+)\s\((.+)\)\sVALUES\s\((.+)\)/i; + const match = query.match(insertRegex); + + if (!match) { + throw new Error("Invalid INSERT INTO syntax."); + } + + const [, table, columns, values] = match; + return { + type: 'INSERT', + table: table.trim(), + columns: columns.split(',').map(column => column.trim()), + values: values.split(',').map(value => value.trim()) + }; +} + + +function parseDeleteQuery(query) { + query = query.trim(); + + // Where Clause logic + const whereSplit = query.split(/\sWHERE\s/i); + query = whereSplit[0]; // Everything before WHERE clause + const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null; + let whereClauses = []; + if (whereClause) { + whereClauses = parseWhereClause(whereClause); + } + + //insert regex + const deleteRegex = /^DELETE FROM\s+(\w+)/i; + const deleteMatch = query.match(deleteRegex); + + if (!deleteMatch) { + throw new Error("Invalid DELETE format"); + } + + const [, table] = deleteMatch; + + return { + type: "DELETE", + table: table.trim(), + whereClauses: whereClauses, + }; + } + +module.exports = { parseSelectQuery,parseJoinClause,parseInsertQuery,parseDeleteQuery }; diff --git a/src/server.js b/src/server.js new file mode 100644 index 000000000..26d31e9f6 --- /dev/null +++ b/src/server.js @@ -0,0 +1 @@ +console.log('server') \ No newline at end of file diff --git a/student.csv b/student.csv new file mode 100644 index 000000000..e9c960121 --- /dev/null +++ b/student.csv @@ -0,0 +1,5 @@ +id,name,age +1,John,30 +2,Jane,25 +3,Bob,22 +4,Alice,24 \ No newline at end of file diff --git a/tests/step-01/index.test.js b/tests/step-01/index.test.js index e42cb72d8..865da85a2 100644 --- a/tests/step-01/index.test.js +++ b/tests/step-01/index.test.js @@ -1,3 +1,5 @@ -test('Basic Jest Test', () => { +test( + "Basic Jest Test", () => { expect(1).toBe(1); -}); \ No newline at end of file +} +); \ No newline at end of file diff --git a/tests/step-02/index.test.js b/tests/step-02/index.test.js index a5467ee48..b9280ef2e 100644 --- a/tests/step-02/index.test.js +++ b/tests/step-02/index.test.js @@ -1,9 +1,13 @@ -const readCSV = require('../../src/csvReader'); +const { readCSV } = require("../../src/csvReader"); + +test( + "Read CSV File", async () => { + + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later -}); \ No newline at end of file + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later +}); + diff --git a/tests/step-03/index.test.js b/tests/step-03/index.test.js index 9145ad3e4..73ad5f943 100644 --- a/tests/step-03/index.test.js +++ b/tests/step-03/index.test.js @@ -1,19 +1,33 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); +const { readCSV } = require("../../src/csvReader"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample' + fields: ["id", "name"], + table: "student", + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false, }); -}); \ No newline at end of file +}); + diff --git a/tests/step-04/index.test.js b/tests/step-04/index.test.js index bc353dd3d..2b356f62d 100644 --- a/tests/step-04/index.test.js +++ b/tests/step-04/index.test.js @@ -1,30 +1,46 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const { readCSV } = require("../../src/csvReader"); +const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser"); +const { executeSELECTQuery } = require("../../src/queryExecutor"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); + expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample' + test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + whereClauses: [], + joinType: null, + joinTable: null, + joinCondition: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + "isDistinct": false, + }); + }); + + test( + "Execute SELECT Query", async () => { + const query = "SELECT id, name FROM student"; + const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -}); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; - const result = await executeSELECTQuery(query); - expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); -}); \ No newline at end of file diff --git a/tests/step-05/index.test.js b/tests/step-05/index.test.js index 66a77c061..18a8d742d 100644 --- a/tests/step-05/index.test.js +++ b/tests/step-05/index.test.js @@ -1,50 +1,75 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); + expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClause: null + fields: ["id", "name"], + table: "student", + whereClauses: [], + joinType: null, + joinCondition: null, + joinTable: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClause: 'age = 25' + fields: ["id", "name"], + table: "student", + whereClauses: [{ + "field": "age", + "operator": "=", + "value": "25", + }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); \ No newline at end of file diff --git a/tests/step-06/index.test.js b/tests/step-06/index.test.js index 2e2ef6416..ea0c50251 100644 --- a/tests/step-06/index.test.js +++ b/tests/step-06/index.test.js @@ -1,79 +1,126 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const { readCSV } = require("../../src/csvReader"); +const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser"); +const { executeSELECTQuery } = require("../../src/queryExecutor"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); - expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); + + expect(data.length).toBeGreaterThan(0); + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later +}); + +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + whereClauses: [], + groupByFields: null, + orderByFields: null, + hasAggregateWithoutGroupBy: false, + joinCondition: null, + joinType: null, + joinTable: null, + limit: null, + isDistinct: false, + }); }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClauses: [] - }); +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; + const result = await executeSELECTQuery(query); + + expect(result.length).toBeGreaterThan(0); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; - const result = await executeSELECTQuery(query); - expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + groupByFields: null, + orderByFields: null, + hasAggregateWithoutGroupBy: false, + joinCondition: null, + joinTable: null, + joinType: null, + whereClauses: [ + { + field: "age", + operator: "=", + value: "25", + }, + ], + limit: null, + isDistinct: false, + }); }); -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClauses: [{ - field: "age", - operator: "=", - value: "25", - }], - }); +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + groupByFields: null, + orderByFields: null, + hasAggregateWithoutGroupBy: false, + joinCondition: null, + joinTable: null, + joinType: null, + whereClauses: [ + { + field: "age", + operator: "=", + value: "30", + }, + { + field: "name", + operator: "=", + value: "John", + }, + ], + limit: null, + isDistinct: false, + }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClauses: [{ - "field": "age", - "operator": "=", - "value": "30", - }, { - "field": "name", - "operator": "=", - "value": "John", - }] - }); +test( + "Execute SQL Query with Multiple WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with Multiple WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); +test( + "Invalid Where Clause", async () => { + const query = "SELECT id, name FROM student WHERE age 30 AND name = John"; + expect(() => { + parseSelectQuery(query); + }).toThrowError("Invalid WHERE clause format"); }); \ No newline at end of file diff --git a/tests/step-07/index.test.js b/tests/step-07/index.test.js index ee0ebed5e..7c7725727 100644 --- a/tests/step-07/index.test.js +++ b/tests/step-07/index.test.js @@ -1,64 +1,86 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./sample.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM sample'; - const parsed = parseQuery(query); +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', - whereClauses: [] + fields: ["id", "name"], + table: "student", + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM sample'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', + fields: ["id", "name"], + table: "student", whereClauses: [{ - field: "age", - operator: "=", - value: "25", + "field": "age", + "operator": "=", + "value": "25", }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'sample', + fields: ["id", "name"], + table: "student", whereClauses: [{ "field": "age", "operator": "=", @@ -67,27 +89,37 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { "field": "name", "operator": "=", "value": "John", - }] + }], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query with Multiple WHERE Clause', async () => { - const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM sample WHERE age > 22'; +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('id'); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("id"); }); -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM sample WHERE age != 25'; +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('name'); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("name"); }); \ No newline at end of file diff --git a/tests/step-08/index.test.js b/tests/step-08/index.test.js index aab1467e6..0a4c660f3 100644 --- a/tests/step-08/index.test.js +++ b/tests/step-08/index.test.js @@ -1,68 +1,89 @@ -const readCSV = require('../../src/csvReader'); -const parseQuery = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(3); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [{ "field": "age", "operator": "=", "value": "25", }], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [{ "field": "age", "operator": "=", @@ -73,57 +94,80 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { "value": "John", }], joinCondition: null, - joinTable: null + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM student WHERE age > 22'; +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('id'); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("id"); }); -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM student WHERE age != 25'; +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(2); - expect(result[0]).toHaveProperty('name'); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("name"); }); -test('Parse SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); +test( + "Parse SQL Query with INNER JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; + const result = await parseSelectQuery(query); expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', + fields: ["student.name", "enrollment.course"], + table: "student", whereClauses: [], - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' } + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20"; + const result = await parseSelectQuery(query); expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [{ field: 'student.age', operator: '>', value: '20' }], - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' } + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [{ field: "student.age", operator: ">", value: "20" }], + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Execute SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with INNER JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); /* result = [ @@ -141,8 +185,9 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { + const query = "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25"; const result = await executeSELECTQuery(query); /* result = [ @@ -164,4 +209,4 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { "enrollment.course": "Mathematics", "student.name": "John" })); -}); \ No newline at end of file +}); diff --git a/tests/step-09/index.test.js b/tests/step-09/index.test.js index aaf711f5a..b644b4788 100644 --- a/tests/step-09/index.test.js +++ b/tests/step-09/index.test.js @@ -1,44 +1,56 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [{ "field": "age", "operator": "=", @@ -46,25 +58,31 @@ test('Parse SQL Query with WHERE Clause', () => { }], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', + fields: ["id", "name"], + table: "student", whereClauses: [{ "field": "age", "operator": "=", @@ -76,59 +94,79 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }], joinCondition: null, joinTable: null, - joinType: null + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); - -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM student WHERE age > 22'; +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('id'); + expect(result[0]).toHaveProperty("id"); }); -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM student WHERE age != 25'; +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('name'); + expect(result[0]).toHaveProperty("name"); }); -test('Parse SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); +test( + "Parse SQL Query with INNER JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; + const result = await parseSelectQuery(query); expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', + fields: ["student.name", "enrollment.course"], + table: "student", whereClauses: [], - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - joinType: 'INNER' + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20"; + const result = await parseSelectQuery(query); expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [{ field: 'student.age', operator: '>', value: '20' }], - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - joinType: 'INNER' + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [{ field: "student.age", operator: ">", value: "20" }], + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Execute SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with INNER JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); /* result = [ @@ -146,8 +184,9 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { + const query = "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25"; const result = await executeSELECTQuery(query); /* result = [ @@ -171,8 +210,9 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with LEFT JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }), @@ -181,8 +221,9 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with LEFT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with LEFT JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }), diff --git a/tests/step-10/index.test.js b/tests/step-10/index.test.js index 5e118eda5..69dfd5a64 100644 --- a/tests/step-10/index.test.js +++ b/tests/step-10/index.test.js @@ -1,57 +1,66 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {parseSelectQuery, parseJoinClause} = require("../../src/queryParser"); +const {executeSELECTQuery} = require("../../src/queryExecutor"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM student WHERE age > 22'; +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('id'); + expect(result[0]).toHaveProperty("id"); }); -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM student WHERE age != 25'; +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('name'); + expect(result[0]).toHaveProperty("name"); }); -test('Execute SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with INNER JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); /* result = [ @@ -69,8 +78,9 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { + const query = "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25"; const result = await executeSELECTQuery(query); /* result = [ @@ -94,8 +104,9 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with LEFT JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }), @@ -104,8 +115,9 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; +test( + "Execute SQL Query with RIGHT JOIN", async () => { + const query = "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }), @@ -114,8 +126,9 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { + const query = "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }), @@ -124,7 +137,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,8 +147,9 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { + const query = "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25"; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }), @@ -143,7 +158,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,45 +168,52 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { - const query = 'SELECT COUNT(*) FROM student'; +test( + "Execute COUNT Aggregate Query", async () => { + const query = "SELECT COUNT(*) FROM student"; const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'COUNT(*)': 4 }]); + expect(result).toEqual([{ "COUNT(*)": 4 }]); }); -test('Execute SUM Aggregate Query', async () => { - const query = 'SELECT SUM(age) FROM student'; +test( + "Execute SUM Aggregate Query", async () => { + const query = "SELECT SUM(age) FROM student"; const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'SUM(age)': 101 }]); + expect(result).toEqual([{ "SUM(age)": 101 }]); }); -test('Execute AVG Aggregate Query', async () => { - const query = 'SELECT AVG(age) FROM student'; +test( + "Execute AVG Aggregate Query", async () => { + const query = "SELECT AVG(age) FROM student"; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { - const query = 'SELECT MIN(age) FROM student'; +test( + "Execute MIN Aggregate Query", async () => { + const query = "SELECT MIN(age) FROM student"; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { - const query = 'SELECT MAX(age) FROM student'; +test( + "Execute MAX Aggregate Query", async () => { + const query = "SELECT MAX(age) FROM student"; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { - const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; +test( + "Count students per age", async () => { + const query = "SELECT age, COUNT(*) FROM student GROUP BY age"; const result = await executeSELECTQuery(query); expect(result).toEqual([ { age: '22', 'COUNT(*)': 1 }, @@ -200,8 +223,9 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { - const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; +test( + "Count enrollments per course", async () => { + const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course"; const result = await executeSELECTQuery(query); expect(result).toEqual([ { course: 'Mathematics', 'COUNT(*)': 2 }, @@ -212,8 +236,9 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { - const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; +test( + "Count courses per student", async () => { + const query = "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id"; const result = await executeSELECTQuery(query); expect(result).toEqual([ { student_id: '1', 'COUNT(*)': 2 }, @@ -223,8 +248,9 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { - const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; +test( + "Count students within a specific age range", async () => { + const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age"; const result = await executeSELECTQuery(query); expect(result).toEqual([ { age: '24', 'COUNT(*)': 1 }, @@ -233,7 +259,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +268,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +277,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -268,12 +298,14 @@ test('Parse SQL Query', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -287,12 +319,14 @@ test('Parse SQL Query with WHERE Clause', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -310,12 +344,14 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -325,12 +361,14 @@ test('Parse SQL Query with INNER JOIN', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -340,10 +378,12 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -353,7 +393,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -363,7 +404,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -373,7 +415,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -385,9 +428,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -397,12 +441,14 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -412,12 +458,14 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -427,12 +475,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,12 +492,14 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -457,12 +509,14 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -472,13 +526,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -488,13 +544,15 @@ test('Parse COUNT Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -504,12 +562,14 @@ test('Parse SUM Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -519,12 +579,13 @@ test('Parse AVG Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse MIN Aggregate Query', () => { +test("Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -534,12 +595,14 @@ test('Parse MIN Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -549,12 +612,14 @@ test('Parse MAX Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, + "orderByFields": null,"limit": null,isDistinct: false, }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -563,13 +628,15 @@ test('Parse basic GROUP BY query', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null,"limit": null,isDistinct: false, }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -578,13 +645,15 @@ test('Parse GROUP BY query with WHERE clause', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null,"limit": null,isDistinct: false, }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -593,13 +662,17 @@ test('Parse GROUP BY query with multiple fields', () => { joinType: null, joinTable: null, joinCondition: null, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null,"limit": null,isDistinct: false, }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { + const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -611,6 +684,7 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { left: 'student.id', right: 'enrollment.student_id' }, - hasAggregateWithoutGroupBy: false + hasAggregateWithoutGroupBy: false, + orderByFields: null,"limit": null,isDistinct: false, }); }); \ No newline at end of file diff --git a/tests/step-11/index.test.js b/tests/step-11/index.test.js index 1cf5f2def..75a74ee55 100644 --- a/tests/step-11/index.test.js +++ b/tests/step-11/index.test.js @@ -1,56 +1,65 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); - -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); + expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM student WHERE age > 22'; +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('id'); + expect(result[0]).toHaveProperty("id"); }); -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM student WHERE age != 25'; +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('name'); + expect(result[0]).toHaveProperty("name"); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +78,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +104,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +115,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +126,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +137,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +147,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +158,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +168,52 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); + expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +224,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +237,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +249,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +260,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +269,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +278,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -268,13 +299,16 @@ test('Parse SQL Query', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -288,13 +322,16 @@ test('Parse SQL Query with WHERE Clause', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -312,13 +349,16 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { joinType: null, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -328,13 +368,16 @@ test('Parse SQL Query with INNER JOIN', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -344,11 +387,14 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -358,7 +404,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +415,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +426,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -390,9 +439,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -402,13 +452,16 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -418,13 +471,16 @@ test('Parse LEFT Join Query Completely', () => { joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -434,13 +490,16 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -450,13 +509,16 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -466,13 +528,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -482,14 +547,17 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }], groupByFields: null, hasAggregateWithoutGroupBy: false, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -499,14 +567,17 @@ test('Parse COUNT Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -516,13 +587,16 @@ test('Parse SUM Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -532,13 +606,16 @@ test('Parse AVG Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -548,13 +625,16 @@ test('Parse MIN Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -564,13 +644,16 @@ test('Parse MAX Aggregate Query', () => { "joinCondition": null, "joinTable": null, "joinType": null, - "orderByFields": null + "orderByFields": null, + "limit": null, + isDistinct: false }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -580,13 +663,16 @@ test('Parse basic GROUP BY query', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -596,13 +682,16 @@ test('Parse GROUP BY query with WHERE clause', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -612,13 +701,16 @@ test('Parse GROUP BY query with multiple fields', () => { joinTable: null, joinCondition: null, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -631,11 +723,14 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { right: 'enrollment.student_id' }, hasAggregateWithoutGroupBy: false, - orderByFields: null + orderByFields: null, + "limit": null, + isDistinct: false, }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -647,7 +742,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -656,7 +752,9 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { + const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); diff --git a/tests/step-12/index.test.js b/tests/step-12/index.test.js index d15c77ef5..4ff83642a 100644 --- a/tests/step-12/index.test.js +++ b/tests/step-12/index.test.js @@ -1,56 +1,67 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +80,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +106,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +117,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +128,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +139,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +149,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +160,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +170,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +225,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +238,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +250,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +261,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +270,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +279,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -269,13 +301,15 @@ test('Parse SQL Query', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -290,13 +324,15 @@ test('Parse SQL Query with WHERE Clause', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -315,13 +351,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -332,13 +370,15 @@ test('Parse SQL Query with INNER JOIN', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -349,11 +389,13 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -363,7 +405,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -373,7 +416,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -383,7 +427,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -395,9 +440,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -408,13 +454,15 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -425,13 +473,15 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,13 +492,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -459,13 +511,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -476,13 +530,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -493,14 +549,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -511,14 +569,16 @@ test('Parse COUNT Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -529,13 +589,15 @@ test('Parse SUM Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -546,13 +608,15 @@ test('Parse AVG Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -563,13 +627,15 @@ test('Parse MIN Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -580,13 +646,15 @@ test('Parse MAX Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -597,13 +665,15 @@ test('Parse basic GROUP BY query', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -614,13 +684,15 @@ test('Parse GROUP BY query with WHERE clause', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -631,13 +703,15 @@ test('Parse GROUP BY query with multiple fields', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -652,10 +726,12 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { hasAggregateWithoutGroupBy: false, orderByFields: null, "limit": null, + isDistinct: false, }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -667,7 +743,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -676,7 +753,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -688,33 +766,39 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); + expect(result.length).toEqual(2); expect(result[0].name).toEqual('John'); expect(result[1].name).toEqual('Jane'); diff --git a/tests/step-13/index.test.js b/tests/step-13/index.test.js index 0797faaba..44b70c93e 100644 --- a/tests/step-13/index.test.js +++ b/tests/step-13/index.test.js @@ -1,27 +1,32 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { +test( + "Execute SQL Query", async () => { const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); @@ -29,28 +34,32 @@ test('Execute SQL Query with WHERE Clause', async () => { expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +78,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +104,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +115,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +126,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +137,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +147,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +158,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +168,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +223,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +236,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +248,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +259,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +268,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +277,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -269,13 +299,15 @@ test('Parse SQL Query', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -290,13 +322,15 @@ test('Parse SQL Query with WHERE Clause', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -315,13 +349,15 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -332,13 +368,15 @@ test('Parse SQL Query with INNER JOIN', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -349,11 +387,13 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -363,7 +403,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -373,7 +414,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -383,7 +425,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -395,9 +438,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -408,13 +452,15 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -425,13 +471,15 @@ test('Parse LEFT Join Query Completely', () => { groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -442,13 +490,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -459,13 +509,15 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -476,13 +528,15 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -493,14 +547,16 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab groupByFields: null, hasAggregateWithoutGroupBy: false, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -511,14 +567,16 @@ test('Parse COUNT Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -529,13 +587,15 @@ test('Parse SUM Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -546,13 +606,15 @@ test('Parse AVG Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -563,13 +625,15 @@ test('Parse MIN Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -580,13 +644,15 @@ test('Parse MAX Aggregate Query', () => { "joinTable": null, "joinType": null, "orderByFields": null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -597,13 +663,15 @@ test('Parse basic GROUP BY query', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -614,13 +682,15 @@ test('Parse GROUP BY query with WHERE clause', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -631,13 +701,15 @@ test('Parse GROUP BY query with multiple fields', () => { joinCondition: null, hasAggregateWithoutGroupBy: false, orderByFields: null, - "limit": null + "limit": null, + isDistinct: false }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -652,10 +724,12 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { hasAggregateWithoutGroupBy: false, orderByFields: null, "limit": null, + isDistinct: false, }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -667,7 +741,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -676,7 +751,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -688,39 +764,46 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); + expect(result.length).toEqual(2); expect(result[0].name).toEqual('John'); expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); \ No newline at end of file diff --git a/tests/step-14/index.test.js b/tests/step-14/index.test.js index 502411fa7..d624491db 100644 --- a/tests/step-14/index.test.js +++ b/tests/step-14/index.test.js @@ -1,59 +1,69 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); - -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); - expect(data.length).toBeGreaterThan(0); - expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later -}); - -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; - const result = await executeSELECTQuery(query); - expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); -}); - -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); -}); - -test('Execute SQL Query with Complex WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const result = await executeSELECTQuery(query); - expect(result.length).toBe(1); - expect(result[0]).toEqual({ id: '1', name: 'John' }); -}); - -test('Execute SQL Query with Greater Than', async () => { - const queryWithGT = 'SELECT id FROM student WHERE age > 22'; - const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('id'); -}); - -test('Execute SQL Query with Not Equal to', async () => { - const queryWithGT = 'SELECT name FROM student WHERE age != 25'; - const result = await executeSELECTQuery(queryWithGT); - expect(result.length).toEqual(3); - expect(result[0]).toHaveProperty('name'); -}); - -test('Execute SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await executeSELECTQuery(query); - /* +const { readCSV } = require("../../src/csvReader"); +const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser"); +const { executeSELECTQuery } = require("../../src/queryExecutor"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); + + expect(data.length).toBeGreaterThan(0); + expect(data.length).toBe(4); + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later +}); + +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; + const result = await executeSELECTQuery(query); + + expect(result.length).toBeGreaterThan(0); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); +}); + +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); +}); + +test( + "Execute SQL Query with Complex WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); + expect(result[0]).toEqual({ id: "1", name: "John" }); +}); + +test( + "Execute SQL Query with Greater Than", async () => { + const queryWithGT = "SELECT id FROM student WHERE age > 22"; + const result = await executeSELECTQuery(queryWithGT); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("id"); +}); + +test( + "Execute SQL Query with Not Equal to", async () => { + const queryWithGT = "SELECT name FROM student WHERE age != 25"; + const result = await executeSELECTQuery(queryWithGT); + expect(result.length).toEqual(3); + expect(result[0]).toHaveProperty("name"); +}); + +test( + "Execute SQL Query with INNER JOIN", async () => { + const query = + "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; + const result = await executeSELECTQuery(query); + /* result = [ { 'student.name': 'John', 'enrollment.course': 'Mathematics' }, { 'student.name': 'John', 'enrollment.course': 'Physics' }, @@ -61,18 +71,22 @@ test('Execute SQL Query with INNER JOIN', async () => { { 'student.name': 'Bob', 'enrollment.course': 'Mathematics' } ] */ - expect(result.length).toEqual(4); - // toHaveProperty is not working here due to dot in the property name - expect(result[0]).toEqual(expect.objectContaining({ - "enrollment.course": "Mathematics", - "student.name": "John" - })); + expect(result.length).toEqual(4); + // toHaveProperty is not working here due to dot in the property name + expect(result[0]).toEqual( + expect.objectContaining({ + "enrollment.course": "Mathematics", + "student.name": "John", + }) + ); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; - const result = await executeSELECTQuery(query); - /* +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { + const query = + "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25"; + const result = await executeSELECTQuery(query); + /* result = [ { 'student.name': 'John', @@ -86,702 +100,834 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { } ] */ - expect(result.length).toEqual(2); - // toHaveProperty is not working here due to dot in the property name - expect(result[0]).toEqual(expect.objectContaining({ - "enrollment.course": "Mathematics", - "student.name": "John" - })); -}); - -test('Execute SQL Query with LEFT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }), - expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" }) - ])); - expect(result.length).toEqual(5); // 4 students, but John appears twice -}); - -test('Execute SQL Query with RIGHT JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }), - expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" }) - ])); - expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice -}); - -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }), - expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" }) - ])); - expect(result.length).toEqual(4); -}); - -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { - const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" }) - ])); - expect(result.length).toEqual(1); -}); - -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }), - expect.objectContaining({ "enrollment.course": "Biology", "student.name": null }) - ])); - expect(result.length).toEqual(2); -}); - -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { - const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await executeSELECTQuery(query); - expect(result).toEqual(expect.arrayContaining([ - expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }), - ])); - expect(result.length).toEqual(1); -}); - -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { - const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; - const result = await executeSELECTQuery(query); - expect(result).toEqual([]); -}); - -test('Execute COUNT Aggregate Query', async () => { - const query = 'SELECT COUNT(*) FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'COUNT(*)': 4 }]); -}); - -test('Execute SUM Aggregate Query', async () => { - const query = 'SELECT SUM(age) FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'SUM(age)': 101 }]); -}); - -test('Execute AVG Aggregate Query', async () => { - const query = 'SELECT AVG(age) FROM student'; - const result = await executeSELECTQuery(query); - // Assuming AVG returns a single decimal point value - expect(result).toEqual([{ 'AVG(age)': 25.25 }]); -}); - -test('Execute MIN Aggregate Query', async () => { - const query = 'SELECT MIN(age) FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'MIN(age)': 22 }]); -}); - -test('Execute MAX Aggregate Query', async () => { - const query = 'SELECT MAX(age) FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ 'MAX(age)': 30 }]); -}); - -test('Count students per age', async () => { - const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { age: '22', 'COUNT(*)': 1 }, - { age: '24', 'COUNT(*)': 1 }, - { age: '25', 'COUNT(*)': 1 }, - { age: '30', 'COUNT(*)': 1 } - ]); -}); - -test('Count enrollments per course', async () => { - const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { course: 'Mathematics', 'COUNT(*)': 2 }, - { course: 'Physics', 'COUNT(*)': 1 }, - { course: 'Chemistry', 'COUNT(*)': 1 }, - { course: 'Biology', 'COUNT(*)': 1 } - ]); -}); - - -test('Count courses per student', async () => { - const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { student_id: '1', 'COUNT(*)': 2 }, - { student_id: '2', 'COUNT(*)': 1 }, - { student_id: '3', 'COUNT(*)': 1 }, - { student_id: '5', 'COUNT(*)': 1 } - ]); -}); - -test('Count students within a specific age range', async () => { - const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { age: '24', 'COUNT(*)': 1 }, - { age: '25', 'COUNT(*)': 1 }, - { age: '30', 'COUNT(*)': 1 } - ]); -}); - -test('Count enrollments for a specific course', async () => { - const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { course: 'Mathematics', 'COUNT(*)': 2 } - ]); -}); - -test('Count courses for a specific student', async () => { - const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([ - { student_id: '1', 'COUNT(*)': 2 } - ]); -}); - -test('Average age of students above a certain age', async () => { - const query = 'SELECT AVG(age) FROM student WHERE age > 22'; - const result = await executeSELECTQuery(query); - const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 - expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); -}); - -test('Parse SQL Query', () => { - const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', - whereClauses: [], - joinCondition: null, - joinTable: null, - joinType: null, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with WHERE Clause', () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', - whereClauses: [{ - "field": "age", - "operator": "=", - "value": "25", - }], - joinCondition: null, - joinTable: null, - joinType: null, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with Multiple WHERE Clauses', () => { - const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['id', 'name'], - table: 'student', - whereClauses: [{ - "field": "age", - "operator": "=", - "value": "30", - }, { - "field": "name", - "operator": "=", - "value": "John", - }], - joinCondition: null, - joinTable: null, - joinType: null, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with INNER JOIN', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); - expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [], - joinTable: 'enrollment', - joinType: "INNER", - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }) -}); - -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { - const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); - expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [{ field: 'student.age', operator: '>', value: '20' }], - joinTable: 'enrollment', - joinType: "INNER", - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }) -}); - -test('Parse INNER JOIN clause', () => { - const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; - const result = parseJoinClause(query); - expect(result).toEqual({ - joinType: 'INNER', - joinTable: 'table2', - joinCondition: { left: 'table1.id', right: 'table2.ref_id' }, - }); -}); - -test('Parse LEFT JOIN clause', () => { - const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; - const result = parseJoinClause(query); - expect(result).toEqual({ - joinType: 'LEFT', - joinTable: 'table2', - joinCondition: { left: 'table1.id', right: 'table2.ref_id' } - }); -}); - -test('Parse RIGHT JOIN clause', () => { - const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; - const result = parseJoinClause(query); - expect(result).toEqual({ - joinType: 'RIGHT', - joinTable: 'table2', - joinCondition: { left: 'table1.id', right: 'table2.ref_id' } - }); -}); - -test('Returns null for queries without JOIN', () => { - const query = 'SELECT * FROM table1'; - const result = parseJoinClause(query); - expect(result).toEqual( - { - joinType: null, - joinTable: null, - joinCondition: null - } - ); -}); - -test('Parse LEFT Join Query Completely', () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); - expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [], - joinType: 'LEFT', - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }) -}) - -test('Parse LEFT Join Query Completely', () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); - expect(result).toEqual({ - fields: ['student.name', 'enrollment.course'], - table: 'student', - whereClauses: [], - joinType: 'RIGHT', - joinTable: 'enrollment', - joinCondition: { left: 'student.id', right: 'enrollment.student_id' }, - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false + expect(result.length).toEqual(2); + // toHaveProperty is not working here due to dot in the property name + expect(result[0]).toEqual( + expect.objectContaining({ + "enrollment.course": "Mathematics", + "student.name": "John", }) -}) - -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); - expect(result).toEqual({ - "fields": ["student.name", "enrollment.course"], - "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, - "joinTable": "enrollment", - "joinType": "LEFT", - "table": "student", - "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }], - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { - const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); - expect(result).toEqual({ - "fields": ["student.name", "enrollment.course"], - "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, - "joinTable": "enrollment", - "joinType": "LEFT", - "table": "student", - "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }], - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { - const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); - expect(result).toEqual({ - "fields": ["student.name", "enrollment.course"], - "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, - "joinTable": "enrollment", - "joinType": "RIGHT", - "table": "student", - "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }], - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { - const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); - expect(result).toEqual({ - "fields": ["student.name", "enrollment.course"], - "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, - "joinTable": "enrollment", - "joinType": "RIGHT", - "table": "student", - "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }], - groupByFields: null, - hasAggregateWithoutGroupBy: false, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - - -test('Parse COUNT Aggregate Query', () => { - const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['COUNT(*)'], - table: 'student', - whereClauses: [], - groupByFields: null, - hasAggregateWithoutGroupBy: true, - "joinCondition": null, - "joinTable": null, - "joinType": null, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - - -test('Parse SUM Aggregate Query', () => { - const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['SUM(age)'], - table: 'student', - whereClauses: [], - groupByFields: null, - hasAggregateWithoutGroupBy: true, - "joinCondition": null, - "joinTable": null, - "joinType": null, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse AVG Aggregate Query', () => { - const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['AVG(age)'], - table: 'student', - whereClauses: [], - groupByFields: null, - hasAggregateWithoutGroupBy: true, - "joinCondition": null, - "joinTable": null, - "joinType": null, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse MIN Aggregate Query', () => { - const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['MIN(age)'], - table: 'student', - whereClauses: [], - groupByFields: null, - hasAggregateWithoutGroupBy: true, - "joinCondition": null, - "joinTable": null, - "joinType": null, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse MAX Aggregate Query', () => { - const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['MAX(age)'], - table: 'student', - whereClauses: [], - groupByFields: null, - hasAggregateWithoutGroupBy: true, - "joinCondition": null, - "joinTable": null, - "joinType": null, - "orderByFields": null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse basic GROUP BY query', () => { - const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['age', 'COUNT(*)'], - table: 'student', - whereClauses: [], - groupByFields: ['age'], - joinType: null, - joinTable: null, - joinCondition: null, - hasAggregateWithoutGroupBy: false, - orderByFields: null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse GROUP BY query with WHERE clause', () => { - const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['age', 'COUNT(*)'], - table: 'student', - whereClauses: [{ field: 'age', operator: '>', value: '22' }], - groupByFields: ['age'], - joinType: null, - joinTable: null, - joinCondition: null, - hasAggregateWithoutGroupBy: false, - orderByFields: null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse GROUP BY query with multiple fields', () => { - const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['student_id', 'course', 'COUNT(*)'], - table: 'enrollment', - whereClauses: [], - groupByFields: ['student_id', 'course'], - joinType: null, - joinTable: null, - joinCondition: null, - hasAggregateWithoutGroupBy: false, - orderByFields: null, - "limit": null, - isDistinct: false - }); -}); - -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { - const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); - expect(parsed).toEqual({ - fields: ['student.name', 'COUNT(*)'], - table: 'student', - whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }], - groupByFields: ['student.name'], - joinType: 'INNER', - joinTable: 'enrollment', - joinCondition: { - left: 'student.id', - right: 'enrollment.student_id' - }, - hasAggregateWithoutGroupBy: false, - orderByFields: null, - "limit": null, - isDistinct: false, - }); -}); - -test('Execute SQL Query with ORDER BY', async () => { - const query = 'SELECT name FROM student ORDER BY name ASC'; - const result = await executeSELECTQuery(query); - - expect(result).toStrictEqual([ - { name: 'Alice' }, - { name: 'Bob' }, - { name: 'Jane' }, - { name: 'John' } - ]); -}); - -test('Execute SQL Query with ORDER BY and WHERE', async () => { - const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; - const result = await executeSELECTQuery(query); - - expect(result).toStrictEqual([ - { name: 'John' }, - { name: 'Jane' }, - ]); -}); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { - const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; - const result = await executeSELECTQuery(query); - - expect(result).toStrictEqual([ - { age: '30', 'COUNT(id) as count': 1 }, - { age: '25', 'COUNT(id) as count': 1 }, - { age: '24', 'COUNT(id) as count': 1 }, - { age: '22', 'COUNT(id) as count': 1 } - ]); -}); - -test('Execute SQL Query with standard LIMIT clause', async () => { - const query = 'SELECT id, name FROM student LIMIT 2'; - const result = await executeSELECTQuery(query); - expect(result.length).toEqual(2); -}); - -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { - const query = 'SELECT id, name FROM student LIMIT 4'; - const result = await executeSELECTQuery(query); - expect(result.length).toEqual(4); -}); - -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { - const query = 'SELECT id, name FROM student LIMIT 10'; - const result = await executeSELECTQuery(query); - expect(result.length).toEqual(4); // Total rows in student.csv -}); - -test('Execute SQL Query with LIMIT 0', async () => { - const query = 'SELECT id, name FROM student LIMIT 0'; - const result = await executeSELECTQuery(query); - expect(result.length).toEqual(0); -}); - -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { - const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; - const result = await executeSELECTQuery(query); - expect(result.length).toEqual(2); - expect(result[0].name).toEqual('John'); - expect(result[1].name).toEqual('Jane'); -}); - -test('Error Handling with Malformed Query', async () => { - const query = 'SELECT FROM table'; // intentionally malformed - await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); -}); - -test('Basic DISTINCT Usage', async () => { - const query = 'SELECT DISTINCT age FROM student'; - const result = await executeSELECTQuery(query); - expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); -}); - -test('DISTINCT with Multiple Columns', async () => { - const query = 'SELECT DISTINCT student_id, course FROM enrollment'; - const result = await executeSELECTQuery(query); - // Expecting unique combinations of student_id and course - expect(result).toEqual([ - { student_id: '1', course: 'Mathematics' }, - { student_id: '1', course: 'Physics' }, - { student_id: '2', course: 'Chemistry' }, - { student_id: '3', course: 'Mathematics' }, - { student_id: '5', course: 'Biology' }, - ]); + ); +}); + +test( + "Execute SQL Query with LEFT JOIN", async () => { + const query = + "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id"; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "student.name": "Alice", + "enrollment.course": null, + }), + expect.objectContaining({ + "student.name": "John", + "enrollment.course": "Mathematics", + }), + ]) + ); + expect(result.length).toEqual(5); // 4 students, but John appears twice +}); + +test( + "Execute SQL Query with RIGHT JOIN", async () => { + const query = + "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id"; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "student.name": null, + "enrollment.course": "Biology", + }), + expect.objectContaining({ + "student.name": "John", + "enrollment.course": "Mathematics", + }), + ]) + ); + expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice +}); + +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { + const query = + "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22"; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "enrollment.course": "Mathematics", + "student.name": "John", + }), + expect.objectContaining({ + "enrollment.course": "Physics", + "student.name": "John", + }), + ]) + ); + expect(result.length).toEqual(4); +}); + +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { + const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "student.name": "John", + "enrollment.course": "Physics", + }), + ]) + ); + expect(result.length).toEqual(1); +}); + +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { + const query = + "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25"; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "enrollment.course": "Mathematics", + "student.name": "Bob", + }), + expect.objectContaining({ + "enrollment.course": "Biology", + "student.name": null, + }), + ]) + ); + expect(result.length).toEqual(2); +}); + +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { + const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; + const result = await executeSELECTQuery(query); + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + "enrollment.course": "Chemistry", + "student.name": "Jane", + }), + ]) + ); + expect(result.length).toEqual(1); +}); + +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { + const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; + const result = await executeSELECTQuery(query); + expect(result).toEqual([]); +}); + +test( + "Execute COUNT Aggregate Query", async () => { + const query = "SELECT COUNT(*) FROM student"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ "COUNT(*)": 4 }]); +}); + +test( + "Execute SUM Aggregate Query", async () => { + const query = "SELECT SUM(age) FROM student"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ "SUM(age)": 101 }]); +}); + +test( + "Execute AVG Aggregate Query", async () => { + const query = "SELECT AVG(age) FROM student"; + const result = await executeSELECTQuery(query); + // Assuming AVG returns a single decimal point value + expect(result).toEqual([{ "AVG(age)": 25.25 }]); +}); + +test( + "Execute MIN Aggregate Query", async () => { + const query = "SELECT MIN(age) FROM student"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ "MIN(age)": 22 }]); +}); + +test( + "Execute MAX Aggregate Query", async () => { + const query = "SELECT MAX(age) FROM student"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ "MAX(age)": 30 }]); +}); + +test( + "Count students per age", async () => { + const query = "SELECT age, COUNT(*) FROM student GROUP BY age"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([ + { age: "22", "COUNT(*)": 1 }, + { age: "24", "COUNT(*)": 1 }, + { age: "25", "COUNT(*)": 1 }, + { age: "30", "COUNT(*)": 1 }, + ]); +}); + +test( + "Count enrollments per course", async () => { + const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([ + { course: "Mathematics", "COUNT(*)": 2 }, + { course: "Physics", "COUNT(*)": 1 }, + { course: "Chemistry", "COUNT(*)": 1 }, + { course: "Biology", "COUNT(*)": 1 }, + ]); +}); + +test( + "Count courses per student", async () => { + const query = + "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([ + { student_id: "1", "COUNT(*)": 2 }, + { student_id: "2", "COUNT(*)": 1 }, + { student_id: "3", "COUNT(*)": 1 }, + { student_id: "5", "COUNT(*)": 1 }, + ]); +}); + +test( + "Count students within a specific age range", async () => { + const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([ + { age: "24", "COUNT(*)": 1 }, + { age: "25", "COUNT(*)": 1 }, + { age: "30", "COUNT(*)": 1 }, + ]); +}); + +test( + "Count enrollments for a specific course", async () => { + const query = + 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]); +}); + +test( + "Count courses for a specific student", async () => { + const query = + "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]); +}); + +test( + "Average age of students above a certain age", async () => { + const query = "SELECT AVG(age) FROM student WHERE age > 22"; + const result = await executeSELECTQuery(query); + const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 + expect(result).toEqual([{ "AVG(age)": expectedAverage }]); +}); + +test( + "Parse SQL Query", () => { + const query = "SELECT id, name FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + whereClauses: [], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with WHERE Clause", () => { + const query = "SELECT id, name FROM student WHERE age = 25"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + whereClauses: [ + { + field: "age", + operator: "=", + value: "25", + }, + ], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { + const query = "SELECT id, name FROM student WHERE age = 30 AND name = John"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["id", "name"], + table: "student", + whereClauses: [ + { + field: "age", + operator: "=", + value: "30", + }, + { + field: "name", + operator: "=", + value: "John", + }, + ], + joinCondition: null, + joinTable: null, + joinType: null, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with INNER JOIN", async () => { + const query = + "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id"; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [], + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { + const query = + "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20"; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [{ field: "student.age", operator: ">", value: "20" }], + joinTable: "enrollment", + joinType: "INNER", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse INNER JOIN clause", () => { + const query = + "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id"; + const result = parseJoinClause(query); + expect(result).toEqual({ + joinType: "INNER", + joinTable: "table2", + joinCondition: { left: "table1.id", right: "table2.ref_id" }, + }); +}); + +test( + "Parse LEFT JOIN clause", () => { + const query = + "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id"; + const result = parseJoinClause(query); + expect(result).toEqual({ + joinType: "LEFT", + joinTable: "table2", + joinCondition: { left: "table1.id", right: "table2.ref_id" }, + }); +}); + +test( + "Parse RIGHT JOIN clause", () => { + const query = + "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id"; + const result = parseJoinClause(query); + expect(result).toEqual({ + joinType: "RIGHT", + joinTable: "table2", + joinCondition: { left: "table1.id", right: "table2.ref_id" }, + }); +}); + +test( + "Returns null for queries without JOIN", () => { + const query = "SELECT * FROM table1"; + const result = parseJoinClause(query); + expect(result).toEqual({ + joinType: null, + joinTable: null, + joinCondition: null, + }); +}); + +test( + "Parse LEFT Join Query Completely", () => { + const query = + "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id"; + const result = parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [], + joinType: "LEFT", + joinTable: "enrollment", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse LEFT Join Query Completely", () => { + const query = + "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id"; + const result = parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + table: "student", + whereClauses: [], + joinType: "RIGHT", + joinTable: "enrollment", + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { + const query = + "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22"; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + joinTable: "enrollment", + joinType: "LEFT", + table: "student", + whereClauses: [{ field: "student.age", operator: ">", value: "22" }], + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { + const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + joinTable: "enrollment", + joinType: "LEFT", + table: "student", + whereClauses: [ + { field: "enrollment.course", operator: "=", value: "'Physics'" }, + ], + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { + const query = + "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25"; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + joinTable: "enrollment", + joinType: "RIGHT", + table: "student", + whereClauses: [{ field: "student.age", operator: "<", value: "25" }], + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { + const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; + const result = await parseSelectQuery(query); + expect(result).toEqual({ + fields: ["student.name", "enrollment.course"], + joinCondition: { left: "student.id", right: "enrollment.student_id" }, + joinTable: "enrollment", + joinType: "RIGHT", + table: "student", + whereClauses: [ + { field: "enrollment.course", operator: "=", value: "'Chemistry'" }, + ], + groupByFields: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse COUNT Aggregate Query", () => { + const query = "SELECT COUNT(*) FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["COUNT(*)"], + table: "student", + whereClauses: [], + groupByFields: null, + hasAggregateWithoutGroupBy: true, + joinCondition: null, + joinTable: null, + joinType: null, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse SUM Aggregate Query", () => { + const query = "SELECT SUM(age) FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["SUM(age)"], + table: "student", + whereClauses: [], + groupByFields: null, + hasAggregateWithoutGroupBy: true, + joinCondition: null, + joinTable: null, + joinType: null, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse AVG Aggregate Query", () => { + const query = "SELECT AVG(age) FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["AVG(age)"], + table: "student", + whereClauses: [], + groupByFields: null, + hasAggregateWithoutGroupBy: true, + joinCondition: null, + joinTable: null, + joinType: null, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse MIN Aggregate Query", () => { + const query = "SELECT MIN(age) FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["MIN(age)"], + table: "student", + whereClauses: [], + groupByFields: null, + hasAggregateWithoutGroupBy: true, + joinCondition: null, + joinTable: null, + joinType: null, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse MAX Aggregate Query", () => { + const query = "SELECT MAX(age) FROM student"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["MAX(age)"], + table: "student", + whereClauses: [], + groupByFields: null, + hasAggregateWithoutGroupBy: true, + joinCondition: null, + joinTable: null, + joinType: null, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse basic GROUP BY query", () => { + const query = "SELECT age, COUNT(*) FROM student GROUP BY age"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["age", "COUNT(*)"], + table: "student", + whereClauses: [], + groupByFields: ["age"], + joinType: null, + joinTable: null, + joinCondition: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse GROUP BY query with WHERE clause", () => { + const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["age", "COUNT(*)"], + table: "student", + whereClauses: [{ field: "age", operator: ">", value: "22" }], + groupByFields: ["age"], + joinType: null, + joinTable: null, + joinCondition: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse GROUP BY query with multiple fields", () => { + const query = + "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course"; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["student_id", "course", "COUNT(*)"], + table: "enrollment", + whereClauses: [], + groupByFields: ["student_id", "course"], + joinType: null, + joinTable: null, + joinCondition: null, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { + const query = + 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; + const parsed = parseSelectQuery(query); + expect(parsed).toEqual({ + fields: ["student.name", "COUNT(*)"], + table: "student", + whereClauses: [ + { field: "enrollment.course", operator: "=", value: '"Mathematics"' }, + ], + groupByFields: ["student.name"], + joinType: "INNER", + joinTable: "enrollment", + joinCondition: { + left: "student.id", + right: "enrollment.student_id", + }, + hasAggregateWithoutGroupBy: false, + orderByFields: null, + limit: null, + isDistinct: false, + }); +}); + +test( + "Execute SQL Query with ORDER BY", async () => { + const query = "SELECT name FROM student ORDER BY name ASC"; + const result = await executeSELECTQuery(query); + + expect(result).toStrictEqual([ + { name: "Alice" }, + { name: "Bob" }, + { name: "Jane" }, + { name: "John" }, + ]); +}); + +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { + const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC"; + const result = await executeSELECTQuery(query); + + expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]); +}); +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { + const query = + "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC"; + const result = await executeSELECTQuery(query); + + expect(result).toStrictEqual([ + { age: "30", "COUNT(id) as count": 1 }, + { age: "25", "COUNT(id) as count": 1 }, + { age: "24", "COUNT(id) as count": 1 }, + { age: "22", "COUNT(id) as count": 1 }, + ]); +}); + +test( + "Execute SQL Query with standard LIMIT clause", async () => { + const query = "SELECT id, name FROM student LIMIT 2"; + const result = await executeSELECTQuery(query); + expect(result.length).toEqual(2); +}); + +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { + const query = "SELECT id, name FROM student LIMIT 4"; + const result = await executeSELECTQuery(query); + expect(result.length).toEqual(4); +}); + +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { + const query = "SELECT id, name FROM student LIMIT 10"; + const result = await executeSELECTQuery(query); + expect(result.length).toEqual(4); // Total rows in student.csv +}); + +test( + "Execute SQL Query with LIMIT 0", async () => { + const query = "SELECT id, name FROM student LIMIT 0"; + const result = await executeSELECTQuery(query); + expect(result.length).toEqual(0); +}); + +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { + const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2"; + const result = await executeSELECTQuery(query); + expect(result.length).toEqual(2); + expect(result[0].name).toEqual("John"); + expect(result[1].name).toEqual("Jane"); +}); + +test( + "Error Handling with Malformed Query", async () => { + const query = "SELECT FROM table"; // intentionally malformed + await expect(executeSELECTQuery(query)).rejects.toThrow( + "Error executing query: Query parsing error: Invalid SELECT format" + ); +}); + +test( + "Basic DISTINCT Usage", async () => { + const query = "SELECT DISTINCT age FROM student"; + const result = await executeSELECTQuery(query); + expect(result).toEqual([ + { age: "30" }, + { age: "25" }, + { age: "22" }, + { age: "24" }, + ]); +}); + +test( + "DISTINCT with Multiple Columns", async () => { + const query = "SELECT DISTINCT student_id, course FROM enrollment"; + const result = await executeSELECTQuery(query); + // Expecting unique combinations of student_id and course + expect(result).toEqual([ + { student_id: "1", course: "Mathematics" }, + { student_id: "1", course: "Physics" }, + { student_id: "2", course: "Chemistry" }, + { student_id: "3", course: "Mathematics" }, + { student_id: "5", course: "Biology" }, + ]); }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { - const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; - const result = await executeSELECTQuery(query); - // Expecting courses taken by student with ID 1 - expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); -}); - -test('DISTINCT with JOIN Operations', async () => { - const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; - const result = await executeSELECTQuery(query); - // Expecting names of students who are enrolled in any course - expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); -}); - -test('DISTINCT with ORDER BY and LIMIT', async () => { - const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; - const result = await executeSELECTQuery(query); - // Expecting the two highest unique ages - expect(result).toEqual([{ age: '30' }, { age: '25' }]); +test( + "DISTINCT with WHERE Clause", async () => { + const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; + const result = await executeSELECTQuery(query); + // Expecting courses taken by student with ID 1 + expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]); +}); + +test( + "DISTINCT with JOIN Operations", async () => { + const query = + "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id"; + const result = await executeSELECTQuery(query); + // Expecting names of students who are enrolled in any course + expect(result).toEqual([ + { "student.name": "John" }, + { "student.name": "Jane" }, + { "student.name": "Bob" }, + ]); +}); + +test( + "DISTINCT with ORDER BY and LIMIT", async () => { + const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2"; + const result = await executeSELECTQuery(query); + + // Expecting the two highest unique ages + expect(result).toEqual([{ age: "30" }, { age: "25" }]); }); \ No newline at end of file diff --git a/tests/step-15/index.test.js b/tests/step-15/index.test.js index a2aa4daee..c547544fe 100644 --- a/tests/step-15/index.test.js +++ b/tests/step-15/index.test.js @@ -1,37 +1,45 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {parseSelectQuery, parseJoinClause} = require("../../src/queryParser"); +const {executeSELECTQuery} = require("../../src/queryExecutor"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test( + "Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0]).not.toHaveProperty('age'); - expect(result[0]).toEqual({ id: '1', name: 'John' }); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0]).not.toHaveProperty("age"); + expect(result[0]).toEqual({ id: "1", name: "John" }); }); -test('Execute SQL Query with WHERE Clause', async () => { - const query = 'SELECT id, name FROM student WHERE age = 25'; +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = "SELECT id, name FROM student WHERE age = 25"; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); - expect(result[0]).toHaveProperty('id'); - expect(result[0]).toHaveProperty('name'); - expect(result[0].id).toBe('2'); + expect(result[0]).toHaveProperty("id"); + expect(result[0]).toHaveProperty("name"); + expect(result[0].id).toBe("2"); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); @@ -43,14 +51,16 @@ test('Execute SQL Query with Greater Than', async () => { expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +79,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +105,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +116,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +127,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +138,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +148,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +159,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +169,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +224,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +237,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +249,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +260,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +269,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +278,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -274,9 +305,10 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -296,9 +328,10 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -322,9 +355,10 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -340,9 +374,10 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -358,7 +393,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +404,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +415,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +426,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,9 +439,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -418,9 +458,10 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -436,9 +477,10 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -454,9 +496,10 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -472,9 +515,10 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -490,9 +534,10 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -509,9 +554,10 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -528,9 +574,10 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -546,9 +593,10 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -564,9 +612,10 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -582,9 +631,10 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -600,9 +650,10 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -618,9 +669,10 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -636,9 +688,10 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -654,9 +707,10 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -675,7 +729,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +742,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +752,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +765,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +802,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,56 +830,64 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test( + "Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test( + "Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( + "Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); // Expecting the first two names alphabetically that contain 'a' diff --git a/tests/step-16/index.test.js b/tests/step-16/index.test.js index a2aa4daee..85ba6454e 100644 --- a/tests/step-16/index.test.js +++ b/tests/step-16/index.test.js @@ -1,18 +1,22 @@ -const readCSV = require('../../src/csvReader'); -const {parseQuery, parseJoinClause} = require('../../src/queryParser'); -const executeSELECTQuery = require('../../src/index'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { +test( + "Execute SQL Query", async () => { const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); @@ -20,37 +24,45 @@ test('Execute SQL Query', async () => { expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with WHERE Clause', async () => { +test( + "Execute SQL Query with WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); + expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +81,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +107,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +118,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +129,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +140,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +150,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +161,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +171,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +226,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +239,7 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test("Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +250,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +269,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,16 +278,18 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -274,9 +305,10 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -296,9 +328,10 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['id', 'name'], table: 'student', @@ -322,9 +355,10 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -340,9 +374,10 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -358,7 +393,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +404,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +415,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +426,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,9 +439,10 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -418,9 +458,10 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; - const result = parseQuery(query); + const result = parseSelectQuery(query); expect(result).toEqual({ fields: ['student.name', 'enrollment.course'], table: 'student', @@ -436,9 +477,10 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -454,9 +496,10 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -472,9 +515,10 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -490,9 +534,10 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; - const result = await parseQuery(query); + const result = await parseSelectQuery(query); expect(result).toEqual({ "fields": ["student.name", "enrollment.course"], "joinCondition": { "left": "student.id", "right": "enrollment.student_id" }, @@ -509,9 +554,10 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['COUNT(*)'], table: 'student', @@ -528,9 +574,10 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['SUM(age)'], table: 'student', @@ -546,9 +593,10 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['AVG(age)'], table: 'student', @@ -564,9 +612,10 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MIN(age)'], table: 'student', @@ -582,9 +631,10 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['MAX(age)'], table: 'student', @@ -600,9 +650,10 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -618,9 +669,10 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['age', 'COUNT(*)'], table: 'student', @@ -636,9 +688,10 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student_id', 'course', 'COUNT(*)'], table: 'enrollment', @@ -654,9 +707,10 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; - const parsed = parseQuery(query); + const parsed = parseSelectQuery(query); expect(parsed).toEqual({ fields: ['student.name', 'COUNT(*)'], table: 'student', @@ -675,7 +729,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +742,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +752,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +765,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +802,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,58 +830,69 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test( + "Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test( + "Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); + // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( +"Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); + // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); + // Expecting the first two names alphabetically that contain 'a' expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]); }); \ No newline at end of file diff --git a/tests/step-17/index.test.js b/tests/step-17/index.test.js index c99d01fbb..4c1cecf4c 100644 --- a/tests/step-17/index.test.js +++ b/tests/step-17/index.test.js @@ -1,18 +1,22 @@ -const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); -const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { +test( + "Execute SQL Query", async () => { const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); @@ -20,7 +24,8 @@ test('Execute SQL Query', async () => { expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with WHERE Clause', async () => { +test( + "Execute SQL Query with WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); @@ -29,28 +34,32 @@ test('Execute SQL Query with WHERE Clause', async () => { expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +78,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +104,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +115,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +126,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +137,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +147,7 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +157,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +167,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +222,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +235,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +247,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +258,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +267,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,14 +276,16 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -274,7 +303,8 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -296,7 +326,8 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -322,7 +353,8 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -340,7 +372,8 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -358,7 +391,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +402,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +413,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +424,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,7 +437,8 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -418,7 +456,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -436,7 +475,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -454,7 +494,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -472,7 +513,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -490,7 +532,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -509,7 +552,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -528,7 +572,8 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -546,7 +591,8 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -564,7 +610,8 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -582,7 +629,8 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -600,7 +648,8 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -618,7 +667,8 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -636,7 +686,8 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -654,7 +705,8 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -675,7 +727,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +740,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +750,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +763,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +800,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,56 +828,64 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test( + "Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test( + "Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( + "Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); // Expecting the first two names alphabetically that contain 'a' diff --git a/tests/step-17/insertExecuter.test.js b/tests/step-17/insertExecuter.test.js index 8c405f727..2f295c449 100644 --- a/tests/step-17/insertExecuter.test.js +++ b/tests/step-17/insertExecuter.test.js @@ -1,5 +1,5 @@ -const { executeINSERTQuery } = require('../../src/index'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeINSERTQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create grades.csv with initial data @@ -9,11 +9,13 @@ async function createGradesCSV() { { student_id: '2', course: 'Chemistry', grade: 'B' }, { student_id: '3', course: 'Mathematics', grade: 'C' } ]; + fs.writeFileSync('grades.csv', ''); await writeCSV('grades.csv', initialData); } // Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { +test( + "Execute INSERT INTO Query for grades.csv", async () => { // Create grades.csv with initial data await createGradesCSV(); @@ -24,7 +26,8 @@ test('Execute INSERT INTO Query for grades.csv', async () => { // Verify the new entry const updatedData = await readCSV('grades.csv'); const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) + + console.log(updatedData); expect(newEntry).toBeDefined(); expect(newEntry.grade).toEqual('A'); diff --git a/tests/step-18/deleteExecutor.test.js b/tests/step-18/deleteExecutor.test.js index 11ae617b7..a603425d6 100644 --- a/tests/step-18/deleteExecutor.test.js +++ b/tests/step-18/deleteExecutor.test.js @@ -1,5 +1,5 @@ -const { executeDELETEQuery } = require('../../src/index'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeDELETEQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create courses.csv with initial data @@ -13,7 +13,9 @@ async function createCoursesCSV() { } // Test to DELETE a course and verify -test('Execute DELETE FROM Query for courses.csv', async () => { +test( + "Execute DELETE FROM Query for courses.csv", async () => { + // Create courses.csv with initial data await createCoursesCSV(); diff --git a/tests/step-18/index.test.js b/tests/step-18/index.test.js index c99d01fbb..975508d9e 100644 --- a/tests/step-18/index.test.js +++ b/tests/step-18/index.test.js @@ -1,18 +1,21 @@ -const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); -const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); - expect(data[0].name).toBe('John'); - expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later + expect(data[0].name).toBe("John"); + expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { - const query = 'SELECT id, name FROM student'; +test("Execute SQL Query", async () => { + const query = "SELECT id, name FROM student"; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); @@ -20,7 +23,8 @@ test('Execute SQL Query', async () => { expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with WHERE Clause', async () => { +test( + "Execute SQL Query with WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); @@ -29,28 +33,32 @@ test('Execute SQL Query with WHERE Clause', async () => { expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +77,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +103,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +114,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +125,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +136,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +146,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +157,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +167,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +222,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +235,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +247,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +258,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +267,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,14 +276,16 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -274,7 +303,8 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -296,7 +326,8 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -322,7 +353,8 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -340,7 +372,8 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -358,7 +391,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +402,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +413,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +424,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,7 +437,8 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -418,7 +456,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -436,7 +475,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -454,7 +494,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -472,7 +513,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -490,7 +532,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -509,7 +552,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -528,7 +572,8 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -546,7 +591,8 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -564,7 +610,8 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -582,7 +629,8 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -600,7 +648,8 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -618,7 +667,8 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -636,7 +686,8 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -654,7 +705,8 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -675,7 +727,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +740,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +750,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +763,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +800,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,58 +828,68 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test( + "Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test( + "Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( + "Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); + // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); + // Expecting the first two names alphabetically that contain 'a' expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]); }); \ No newline at end of file diff --git a/tests/step-18/insertExecuter.test.js b/tests/step-18/insertExecuter.test.js index 8c405f727..08af4ce46 100644 --- a/tests/step-18/insertExecuter.test.js +++ b/tests/step-18/insertExecuter.test.js @@ -1,5 +1,5 @@ -const { executeINSERTQuery } = require('../../src/index'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeINSERTQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create grades.csv with initial data @@ -13,7 +13,8 @@ async function createGradesCSV() { } // Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { +test( + "Execute INSERT INTO Query for grades.csv", async () => { // Create grades.csv with initial data await createGradesCSV(); @@ -24,7 +25,8 @@ test('Execute INSERT INTO Query for grades.csv', async () => { // Verify the new entry const updatedData = await readCSV('grades.csv'); const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) + + console.log(updatedData); expect(newEntry).toBeDefined(); expect(newEntry.grade).toEqual('A'); diff --git a/tests/step-19/cli.js b/tests/step-19/cli.js index fbba6c02c..5f0a51b37 100644 --- a/tests/step-19/cli.js +++ b/tests/step-19/cli.js @@ -1,7 +1,9 @@ -const child_process = require('child_process'); -const path = require('path'); +const child_process = require("child_process"); +const path = require("path"); + +test( + "DISTINCT with Multiple Columns via CLI", (done) => { -test('DISTINCT with Multiple Columns via CLI', (done) => { const cliPath = path.join(__dirname, '..', 'src', 'cli.js'); const cliProcess = child_process.spawn('node', [cliPath]); @@ -11,11 +13,13 @@ test('DISTINCT with Multiple Columns via CLI', (done) => { }); cliProcess.on('exit', () => { + // Define a regex pattern to extract the JSON result const cleanedOutput = outputData.replace(/\s+/g, ' '); const resultRegex = /Result: (\[.+\])/s; const match = cleanedOutput.match(resultRegex); + // Fix JSON outputput match[1] = match[1].replace(/'/g, '"').replace(/(\w+):/g, '"$1":'); @@ -39,7 +43,6 @@ test('DISTINCT with Multiple Columns via CLI', (done) => { done() throw new Error('Failed to parse CLI output'); } - done(); }); diff --git a/tests/step-19/deleteExecutor.test.js b/tests/step-19/deleteExecutor.test.js index 11ae617b7..0cc88eadf 100644 --- a/tests/step-19/deleteExecutor.test.js +++ b/tests/step-19/deleteExecutor.test.js @@ -1,5 +1,5 @@ -const { executeDELETEQuery } = require('../../src/index'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeDELETEQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create courses.csv with initial data @@ -13,17 +13,21 @@ async function createCoursesCSV() { } // Test to DELETE a course and verify -test('Execute DELETE FROM Query for courses.csv', async () => { +test( + "Execute DELETE FROM Query for courses.csv", async () => { + // Create courses.csv with initial data await createCoursesCSV(); // Execute DELETE statement + const deleteQuery = "DELETE FROM courses WHERE course_id = '2'"; await executeDELETEQuery(deleteQuery); // Verify the course was removed const updatedData = await readCSV('courses.csv'); const deletedCourse = updatedData.find(course => course.course_id === '2'); + expect(deletedCourse).toBeUndefined(); // Cleanup: Delete courses.csv diff --git a/tests/step-19/index.test.js b/tests/step-19/index.test.js index c99d01fbb..568c35182 100644 --- a/tests/step-19/index.test.js +++ b/tests/step-19/index.test.js @@ -1,18 +1,22 @@ -const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/index'); -const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); -test('Read CSV File', async () => { +test( + "Read CSV File", async () => { const data = await readCSV('./student.csv'); + expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { +test( + "Execute SQL Query", async () => { const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); @@ -20,37 +24,46 @@ test('Execute SQL Query', async () => { expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with WHERE Clause', async () => { +test( + "Execute SQL Query with WHERE Clause", async () => { + const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); + expect(result.length).toBe(1); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); + + expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +82,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +108,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +119,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +130,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +141,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +151,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +162,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +172,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +227,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +240,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +252,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +263,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +272,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,14 +281,16 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -274,7 +308,8 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -296,7 +331,8 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -322,7 +358,8 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -340,7 +377,8 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -358,7 +396,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +407,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +418,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +429,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,7 +442,8 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -418,7 +461,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -436,7 +480,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -454,7 +499,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -472,7 +518,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -490,7 +537,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -509,7 +557,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -528,7 +577,8 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -546,7 +596,8 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -564,7 +615,8 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -582,7 +634,8 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -600,7 +653,8 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -618,7 +672,8 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -636,7 +691,8 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -654,7 +710,8 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -675,7 +732,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +745,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +755,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +768,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +805,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,58 +833,68 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test( + "Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test( + "Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( + "Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); + // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); + // Expecting the first two names alphabetically that contain 'a' expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]); }); \ No newline at end of file diff --git a/tests/step-19/insertExecuter.test.js b/tests/step-19/insertExecuter.test.js index 8c405f727..937e02862 100644 --- a/tests/step-19/insertExecuter.test.js +++ b/tests/step-19/insertExecuter.test.js @@ -1,5 +1,5 @@ -const { executeINSERTQuery } = require('../../src/index'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeINSERTQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create grades.csv with initial data @@ -13,21 +13,29 @@ async function createGradesCSV() { } // Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { +test( + "Execute INSERT INTO Query for grades.csv", async () => { // Create grades.csv with initial data await createGradesCSV(); + // Execute INSERT statement - const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; + const insertQuery = + "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')"; + await executeINSERTQuery(insertQuery); + // Verify the new entry const updatedData = await readCSV('grades.csv'); + const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); - console.log(updatedData) + + console.log(updatedData); expect(newEntry).toBeDefined(); expect(newEntry.grade).toEqual('A'); + // Cleanup: Delete grades.csv fs.unlinkSync('grades.csv'); }); \ No newline at end of file diff --git a/tests/step-20/cli.js b/tests/step-20/cli.js index fbba6c02c..8a6ea8878 100644 --- a/tests/step-20/cli.js +++ b/tests/step-20/cli.js @@ -1,7 +1,8 @@ -const child_process = require('child_process'); -const path = require('path'); +const child_process = require("child_process"); +const path = require("path"); -test('DISTINCT with Multiple Columns via CLI', (done) => { +test( + "DISTINCT with Multiple Columns via CLI", (done) => { const cliPath = path.join(__dirname, '..', 'src', 'cli.js'); const cliProcess = child_process.spawn('node', [cliPath]); @@ -12,10 +13,12 @@ test('DISTINCT with Multiple Columns via CLI', (done) => { cliProcess.on('exit', () => { // Define a regex pattern to extract the JSON result + const cleanedOutput = outputData.replace(/\s+/g, ' '); const resultRegex = /Result: (\[.+\])/s; const match = cleanedOutput.match(resultRegex); + // Fix JSON outputput match[1] = match[1].replace(/'/g, '"').replace(/(\w+):/g, '"$1":'); @@ -39,7 +42,6 @@ test('DISTINCT with Multiple Columns via CLI', (done) => { done() throw new Error('Failed to parse CLI output'); } - done(); }); diff --git a/tests/step-20/deleteExecutor.test.js b/tests/step-20/deleteExecutor.test.js index 636403858..709ef76ae 100644 --- a/tests/step-20/deleteExecutor.test.js +++ b/tests/step-20/deleteExecutor.test.js @@ -1,5 +1,5 @@ -const { executeDELETEQuery } = require('../../src/queryExecutor'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeDELETEQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create courses.csv with initial data @@ -13,11 +13,14 @@ async function createCoursesCSV() { } // Test to DELETE a course and verify -test('Execute DELETE FROM Query for courses.csv', async () => { +test( + "Execute DELETE FROM Query for courses.csv", async () => { + // Create courses.csv with initial data await createCoursesCSV(); // Execute DELETE statement + const deleteQuery = "DELETE FROM courses WHERE course_id = '2'"; await executeDELETEQuery(deleteQuery); diff --git a/tests/step-20/index.test.js b/tests/step-20/index.test.js index dc1fa19ae..a2bbd3439 100644 --- a/tests/step-20/index.test.js +++ b/tests/step-20/index.test.js @@ -1,18 +1,22 @@ -const {readCSV} = require('../../src/csvReader'); -const {executeSELECTQuery } = require('../../src/queryExecutor'); -const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser'); +const {readCSV} = require("../../src/csvReader"); +const {executeSELECTQuery } = require("../../src/queryExecutor"); +const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser"); + +test( + "Read CSV File", async () => { + const data = await readCSV("./student.csv"); -test('Read CSV File', async () => { - const data = await readCSV('./student.csv'); expect(data.length).toBeGreaterThan(0); expect(data.length).toBe(4); expect(data[0].name).toBe('John'); expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later }); -test('Execute SQL Query', async () => { +test( + "Execute SQL Query", async () => { const query = 'SELECT id, name FROM student'; const result = await executeSELECTQuery(query); + expect(result.length).toBeGreaterThan(0); expect(result[0]).toHaveProperty('id'); expect(result[0]).toHaveProperty('name'); @@ -20,7 +24,8 @@ test('Execute SQL Query', async () => { expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with WHERE Clause', async () => { +test( + "Execute SQL Query with WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); @@ -29,28 +34,32 @@ test('Execute SQL Query with WHERE Clause', async () => { expect(result[0].id).toBe('2'); }); -test('Execute SQL Query with Complex WHERE Clause', async () => { +test( + "Execute SQL Query with Complex WHERE Clause", async () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const result = await executeSELECTQuery(query); expect(result.length).toBe(1); expect(result[0]).toEqual({ id: '1', name: 'John' }); }); -test('Execute SQL Query with Greater Than', async () => { +test( + "Execute SQL Query with Greater Than", async () => { const queryWithGT = 'SELECT id FROM student WHERE age > 22'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('id'); }); -test('Execute SQL Query with Not Equal to', async () => { +test( + "Execute SQL Query with Not Equal to", async () => { const queryWithGT = 'SELECT name FROM student WHERE age != 25'; const result = await executeSELECTQuery(queryWithGT); expect(result.length).toEqual(3); expect(result[0]).toHaveProperty('name'); }); -test('Execute SQL Query with INNER JOIN', async () => { +test( + "Execute SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); /* @@ -69,7 +78,8 @@ test('Execute SQL Query with INNER JOIN', async () => { })); }); -test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { +test( + "Execute SQL Query with INNER JOIN and a WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25'; const result = await executeSELECTQuery(query); /* @@ -94,7 +104,8 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => { })); }); -test('Execute SQL Query with LEFT JOIN', async () => { +test( + "Execute SQL Query with LEFT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -104,7 +115,8 @@ test('Execute SQL Query with LEFT JOIN', async () => { expect(result.length).toEqual(5); // 4 students, but John appears twice }); -test('Execute SQL Query with RIGHT JOIN', async () => { +test( + "Execute SQL Query with RIGHT JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -114,7 +126,8 @@ test('Execute SQL Query with RIGHT JOIN', async () => { expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -124,7 +137,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main ta expect(result.length).toEqual(4); }); -test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -133,7 +147,8 @@ test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join ta expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -143,7 +158,8 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main t expect(result.length).toEqual(2); }); -test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await executeSELECTQuery(query); expect(result).toEqual(expect.arrayContaining([ @@ -152,44 +168,51 @@ test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join t expect(result.length).toEqual(1); }); -test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => { +test( + "Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`; const result = await executeSELECTQuery(query); expect(result).toEqual([]); }); -test('Execute COUNT Aggregate Query', async () => { +test( + "Execute COUNT Aggregate Query", async () => { const query = 'SELECT COUNT(*) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'COUNT(*)': 4 }]); }); -test('Execute SUM Aggregate Query', async () => { +test( + "Execute SUM Aggregate Query", async () => { const query = 'SELECT SUM(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'SUM(age)': 101 }]); }); -test('Execute AVG Aggregate Query', async () => { +test( + "Execute AVG Aggregate Query", async () => { const query = 'SELECT AVG(age) FROM student'; const result = await executeSELECTQuery(query); // Assuming AVG returns a single decimal point value expect(result).toEqual([{ 'AVG(age)': 25.25 }]); }); -test('Execute MIN Aggregate Query', async () => { +test( + "Execute MIN Aggregate Query", async () => { const query = 'SELECT MIN(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MIN(age)': 22 }]); }); -test('Execute MAX Aggregate Query', async () => { +test( + "Execute MAX Aggregate Query", async () => { const query = 'SELECT MAX(age) FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ 'MAX(age)': 30 }]); }); -test('Count students per age', async () => { +test( + "Count students per age", async () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -200,7 +223,8 @@ test('Count students per age', async () => { ]); }); -test('Count enrollments per course', async () => { +test( + "Count enrollments per course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -212,7 +236,8 @@ test('Count enrollments per course', async () => { }); -test('Count courses per student', async () => { +test( + "Count courses per student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -223,7 +248,8 @@ test('Count courses per student', async () => { ]); }); -test('Count students within a specific age range', async () => { +test( + "Count students within a specific age range", async () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -233,7 +259,8 @@ test('Count students within a specific age range', async () => { ]); }); -test('Count enrollments for a specific course', async () => { +test( + "Count enrollments for a specific course", async () => { const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -241,7 +268,8 @@ test('Count enrollments for a specific course', async () => { ]); }); -test('Count courses for a specific student', async () => { +test( + "Count courses for a specific student", async () => { const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id'; const result = await executeSELECTQuery(query); expect(result).toEqual([ @@ -249,14 +277,16 @@ test('Count courses for a specific student', async () => { ]); }); -test('Average age of students above a certain age', async () => { +test( + "Average age of students above a certain age", async () => { const query = 'SELECT AVG(age) FROM student WHERE age > 22'; const result = await executeSELECTQuery(query); const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22 expect(result).toEqual([{ 'AVG(age)': expectedAverage }]); }); -test('Parse SQL Query', () => { +test( + "Parse SQL Query", () => { const query = 'SELECT id, name FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -274,7 +304,8 @@ test('Parse SQL Query', () => { }); }); -test('Parse SQL Query with WHERE Clause', () => { +test( + "Parse SQL Query with WHERE Clause", () => { const query = 'SELECT id, name FROM student WHERE age = 25'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -296,7 +327,8 @@ test('Parse SQL Query with WHERE Clause', () => { }); }); -test('Parse SQL Query with Multiple WHERE Clauses', () => { +test( + "Parse SQL Query with Multiple WHERE Clauses", () => { const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -322,7 +354,8 @@ test('Parse SQL Query with Multiple WHERE Clauses', () => { }); }); -test('Parse SQL Query with INNER JOIN', async () => { +test( + "Parse SQL Query with INNER JOIN", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -340,7 +373,8 @@ test('Parse SQL Query with INNER JOIN', async () => { }) }); -test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { +test( + "Parse SQL Query with INNER JOIN and WHERE Clause", async () => { const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -358,7 +392,8 @@ test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => { }) }); -test('Parse INNER JOIN clause', () => { +test( + "Parse INNER JOIN clause", () => { const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -368,7 +403,8 @@ test('Parse INNER JOIN clause', () => { }); }); -test('Parse LEFT JOIN clause', () => { +test( + "Parse LEFT JOIN clause", () => { const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -378,7 +414,8 @@ test('Parse LEFT JOIN clause', () => { }); }); -test('Parse RIGHT JOIN clause', () => { +test( + "Parse RIGHT JOIN clause", () => { const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id'; const result = parseJoinClause(query); expect(result).toEqual({ @@ -388,7 +425,8 @@ test('Parse RIGHT JOIN clause', () => { }); }); -test('Returns null for queries without JOIN', () => { +test( + "Returns null for queries without JOIN", () => { const query = 'SELECT * FROM table1'; const result = parseJoinClause(query); expect(result).toEqual( @@ -400,7 +438,8 @@ test('Returns null for queries without JOIN', () => { ); }); -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -418,7 +457,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse LEFT Join Query Completely', () => { +test( + "Parse LEFT Join Query Completely", () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id'; const result = parseSelectQuery(query); expect(result).toEqual({ @@ -436,7 +476,8 @@ test('Parse LEFT Join Query Completely', () => { }) }) -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -454,7 +495,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main tabl }); }); -test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -472,7 +514,8 @@ test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join tabl }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => { const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25'; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -490,7 +533,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main tab }); }); -test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => { +test( + "Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => { const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`; const result = await parseSelectQuery(query); expect(result).toEqual({ @@ -509,7 +553,8 @@ test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join tab }); -test('Parse COUNT Aggregate Query', () => { +test( + "Parse COUNT Aggregate Query", () => { const query = 'SELECT COUNT(*) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -528,7 +573,8 @@ test('Parse COUNT Aggregate Query', () => { }); -test('Parse SUM Aggregate Query', () => { +test( + "Parse SUM Aggregate Query", () => { const query = 'SELECT SUM(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -546,7 +592,8 @@ test('Parse SUM Aggregate Query', () => { }); }); -test('Parse AVG Aggregate Query', () => { +test( + "Parse AVG Aggregate Query", () => { const query = 'SELECT AVG(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -564,7 +611,8 @@ test('Parse AVG Aggregate Query', () => { }); }); -test('Parse MIN Aggregate Query', () => { +test( + "Parse MIN Aggregate Query", () => { const query = 'SELECT MIN(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -582,7 +630,8 @@ test('Parse MIN Aggregate Query', () => { }); }); -test('Parse MAX Aggregate Query', () => { +test( + "Parse MAX Aggregate Query", () => { const query = 'SELECT MAX(age) FROM student'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -600,7 +649,8 @@ test('Parse MAX Aggregate Query', () => { }); }); -test('Parse basic GROUP BY query', () => { +test( + "Parse basic GROUP BY query", () => { const query = 'SELECT age, COUNT(*) FROM student GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -618,7 +668,8 @@ test('Parse basic GROUP BY query', () => { }); }); -test('Parse GROUP BY query with WHERE clause', () => { +test( + "Parse GROUP BY query with WHERE clause", () => { const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -636,7 +687,8 @@ test('Parse GROUP BY query with WHERE clause', () => { }); }); -test('Parse GROUP BY query with multiple fields', () => { +test( + "Parse GROUP BY query with multiple fields", () => { const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -654,7 +706,8 @@ test('Parse GROUP BY query with multiple fields', () => { }); }); -test('Parse GROUP BY query with JOIN and WHERE clauses', () => { +test( + "Parse GROUP BY query with JOIN and WHERE clauses", () => { const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name'; const parsed = parseSelectQuery(query); expect(parsed).toEqual({ @@ -675,7 +728,8 @@ test('Parse GROUP BY query with JOIN and WHERE clauses', () => { }); }); -test('Execute SQL Query with ORDER BY', async () => { +test( + "Execute SQL Query with ORDER BY", async () => { const query = 'SELECT name FROM student ORDER BY name ASC'; const result = await executeSELECTQuery(query); @@ -687,7 +741,8 @@ test('Execute SQL Query with ORDER BY', async () => { ]); }); -test('Execute SQL Query with ORDER BY and WHERE', async () => { +test( + "Execute SQL Query with ORDER BY and WHERE", async () => { const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC'; const result = await executeSELECTQuery(query); @@ -696,7 +751,8 @@ test('Execute SQL Query with ORDER BY and WHERE', async () => { { name: 'Jane' }, ]); }); -test('Execute SQL Query with ORDER BY and GROUP BY', async () => { +test( + "Execute SQL Query with ORDER BY and GROUP BY", async () => { const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC'; const result = await executeSELECTQuery(query); @@ -708,31 +764,36 @@ test('Execute SQL Query with ORDER BY and GROUP BY', async () => { ]); }); -test('Execute SQL Query with standard LIMIT clause', async () => { +test( + "Execute SQL Query with standard LIMIT clause", async () => { const query = 'SELECT id, name FROM student LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); }); -test('Execute SQL Query with LIMIT clause equal to total rows', async () => { +test( + "Execute SQL Query with LIMIT clause equal to total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 4'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); }); -test('Execute SQL Query with LIMIT clause exceeding total rows', async () => { +test( + "Execute SQL Query with LIMIT clause exceeding total rows", async () => { const query = 'SELECT id, name FROM student LIMIT 10'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(4); // Total rows in student.csv }); -test('Execute SQL Query with LIMIT 0', async () => { +test( + "Execute SQL Query with LIMIT 0", async () => { const query = 'SELECT id, name FROM student LIMIT 0'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(0); }); -test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { +test( + "Execute SQL Query with LIMIT and ORDER BY clause", async () => { const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); expect(result.length).toEqual(2); @@ -740,18 +801,21 @@ test('Execute SQL Query with LIMIT and ORDER BY clause', async () => { expect(result[1].name).toEqual('Jane'); }); -test('Error Handling with Malformed Query', async () => { +test( + "Error Handling with Malformed Query", async () => { const query = 'SELECT FROM table'; // intentionally malformed await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format"); }); -test('Basic DISTINCT Usage', async () => { +test( + "Basic DISTINCT Usage", async () => { const query = 'SELECT DISTINCT age FROM student'; const result = await executeSELECTQuery(query); expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]); }); -test('DISTINCT with Multiple Columns', async () => { +test( + "DISTINCT with Multiple Columns", async () => { const query = 'SELECT DISTINCT student_id, course FROM enrollment'; const result = await executeSELECTQuery(query); // Expecting unique combinations of student_id and course @@ -765,58 +829,66 @@ test('DISTINCT with Multiple Columns', async () => { }); // Not a good test right now -test('DISTINCT with WHERE Clause', async () => { +test( + "DISTINCT with WHERE Clause", async () => { const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"'; const result = await executeSELECTQuery(query); // Expecting courses taken by student with ID 1 expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]); }); -test('DISTINCT with JOIN Operations', async () => { +test( + "DISTINCT with JOIN Operations", async () => { const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id'; const result = await executeSELECTQuery(query); // Expecting names of students who are enrolled in any course expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]); }); -test('DISTINCT with ORDER BY and LIMIT', async () => { +test( + "DISTINCT with ORDER BY and LIMIT", async () => { const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2'; const result = await executeSELECTQuery(query); // Expecting the two highest unique ages expect(result).toEqual([{ age: '30' }, { age: '25' }]); }); -test('Execute SQL Query with LIKE Operator for Name', async () => { +test("Execute SQL Query with LIKE Operator for Name", async () => { const query = "SELECT name FROM student WHERE name LIKE '%Jane%'"; const result = await executeSELECTQuery(query); // Expecting names containing 'Jane' expect(result).toEqual([{ name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator and Wildcards', async () => { +test("Execute SQL Query with LIKE Operator and Wildcards", async () => { const query = "SELECT name FROM student WHERE name LIKE 'J%'"; const result = await executeSELECTQuery(query); // Expecting names starting with 'J' expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]); }); -test('Execute SQL Query with LIKE Operator Case Insensitive', async () => { +test( + "Execute SQL Query with LIKE Operator Case Insensitive", async () => { const query = "SELECT name FROM student WHERE name LIKE '%bob%'"; const result = await executeSELECTQuery(query); // Expecting names 'Bob' (case insensitive) expect(result).toEqual([{ name: 'Bob' }]); }); -test('Execute SQL Query with LIKE Operator and DISTINCT', async () => { +test( +"Execute SQL Query with LIKE Operator and DISTINCT", async () => { const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'"; const result = await executeSELECTQuery(query); + // Expecting unique names containing 'e' expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]); }); -test('LIKE with ORDER BY and LIMIT', async () => { +test( + "LIKE with ORDER BY and LIMIT", async () => { const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2"; const result = await executeSELECTQuery(query); + // Expecting the first two names alphabetically that contain 'a' expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]); }); \ No newline at end of file diff --git a/tests/step-20/insertExecuter.test.js b/tests/step-20/insertExecuter.test.js index 581d17f73..eca019bed 100644 --- a/tests/step-20/insertExecuter.test.js +++ b/tests/step-20/insertExecuter.test.js @@ -1,5 +1,5 @@ -const { executeINSERTQuery } = require('../../src/queryExecutor'); -const { readCSV, writeCSV } = require('../../src/csvReader'); +const { executeINSERTQuery } = require("../../src/queryExecutor"); +const { readCSV, writeCSV } = require("../../src/csvReader"); const fs = require('fs'); // Helper function to create grades.csv with initial data @@ -13,7 +13,8 @@ async function createGradesCSV() { } // Test to INSERT a new grade and verify -test('Execute INSERT INTO Query for grades.csv', async () => { +test( + "Execute INSERT INTO Query for grades.csv", async () => { // Create grades.csv with initial data await createGradesCSV(); @@ -24,6 +25,7 @@ test('Execute INSERT INTO Query for grades.csv', async () => { // Verify the new entry const updatedData = await readCSV('grades.csv'); const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics'); + console.log(updatedData) expect(newEntry).toBeDefined(); expect(newEntry.grade).toEqual('A');