From 2ff11e19a6fd321b86eb41a7f8545a661ab93fdc Mon Sep 17 00:00:00 2001 From: Matthew Hambrecht Date: Sun, 10 Aug 2025 14:29:55 -0400 Subject: [PATCH] Cleaned conditional literal, renamed unit tests --- src/language/parser/conditional.rs | 65 +++++++++++++++++++++++++----- src/language/parser/get.rs | 9 +---- tests/transpiler_tests.rs | 38 ++++++++--------- tests/validator_tests.rs | 32 +++++++-------- 4 files changed, 92 insertions(+), 52 deletions(-) diff --git a/src/language/parser/conditional.rs b/src/language/parser/conditional.rs index aad9058..58e5bf5 100644 --- a/src/language/parser/conditional.rs +++ b/src/language/parser/conditional.rs @@ -1,4 +1,5 @@ use std::fmt; + use crate::{ language::{ parser::helpers::{ @@ -435,6 +436,58 @@ fn recurse_down( } impl ConditionNode { + /// Reconstructs conditional literal from provided tokens + /// and bounds. + fn reconstruct_literal ( + tokens: &Vec, + start_idx: usize, + end_idx: usize, + ) -> String { + // Reconstruct literal + let mut i: usize = start_idx; + let mut literal = String::new(); + + while i < end_idx { + match tokens[i].token_type { + TokenType::OpenParen | TokenType::CloseParen => { + literal.push_str(&tokens[i].lexeme); + i += 1; + } + TokenType::And | TokenType::Or => { + literal.push_str(&format!(" {} ", &tokens[i].lexeme)); + i += 1; + } + TokenType::Identifier => { + let mut j = i; + let mut parts = Vec::new(); + + while parts.len() < 3 + { + parts.push(if tokens[j].token_type == TokenType::Equal { + "=".to_string() + } else { + tokens[j].lexeme.clone() + } + ); + j += 1; + } + + if !parts.is_empty() { + literal.push_str(&parts.join(" ")); + } + + i = j; + } + _ => { + literal.push_str(&tokens[i].lexeme); + i += 1; + } + } + } + + literal + } + /// Takes current node type and given the current location in the /// query defined by the borrowed index, makes an attempt to parse /// this node and associated subnodes for the Abstract Syntax Tree. @@ -482,20 +535,12 @@ impl ConditionNode { return Err("Conditional had unclosed parentheses".to_string()); } + return Ok( ConditionNode { _condition: ret, _depth: depth, - _literal: { - tokens[start_idx..*idx].iter() - .map(|v| if v.token_type == TokenType::Equal { - "=" - } else { - v.lexeme.as_str() - }) - .collect::>() - .join(" ") - } + _literal: ConditionNode::reconstruct_literal(tokens, start_idx, *idx) } ) } diff --git a/src/language/parser/get.rs b/src/language/parser/get.rs index 444246c..4241ca9 100644 --- a/src/language/parser/get.rs +++ b/src/language/parser/get.rs @@ -388,12 +388,7 @@ impl FilterNode { Some(FilterNode { condition: condition_node, - _literal: { - tokens[start_idx..*idx].iter() - .map(|v| v.lexeme.as_str()) - .collect::>() - .join(" ") - }, + _literal: tokens[start_idx].lexeme.clone(), _depth: depth })); } @@ -408,7 +403,7 @@ impl FilterNode { &self ) -> (String, String) { ( - colorize(&self._literal, AnsiColor::Cyan), + colorize(&format!("{} {}", self._literal, self.condition.transpile_raw()), AnsiColor::Cyan), colorize(&format!("WHERE {}", self.condition.transpile_color()), AnsiColor::Cyan) ) } diff --git a/tests/transpiler_tests.rs b/tests/transpiler_tests.rs index 09f7f6f..124c758 100644 --- a/tests/transpiler_tests.rs +++ b/tests/transpiler_tests.rs @@ -3,28 +3,28 @@ use eaql::transpiler::engine; // Database Query Tests (Validator) // Normal #[test] -fn integration_test_db_create_normal() { +fn transpile_integration_test_db_create_normal() { // Create keyword tests assert_eq!(engine("create database test;"), Ok("CREATE DATABASE test;".to_string())); assert_eq!(engine("make database test."), Ok("CREATE DATABASE test;".to_string())); } #[test] -fn integration_test_db_use_normal() { +fn transpile_integration_test_db_use_normal() { // Use keyword tests assert_eq!(engine("use database test;"), Ok("USE DATABASE test;".to_string())); assert_eq!(engine("enter database test;"), Ok("USE DATABASE test;".to_string())); } #[test] -fn integration_test_db_show_normal() { +fn transpile_integration_test_db_show_normal() { // Show keyword tests assert_eq!(engine("show database;"), Ok("SHOW DATABASES;".to_string())); assert_eq!(engine("list databases."), Ok("SHOW DATABASES;".to_string())); } #[test] -fn integration_test_db_destroy_normal() { +fn transpile_integration_test_db_destroy_normal() { // Destroy assert_eq!(engine("remove database db1!"), Ok("DROP DATABASE db1;".to_string())); assert_eq!(engine("destroy database db1!"), Ok("DROP DATABASE db1;".to_string())); @@ -37,7 +37,7 @@ fn integration_test_db_destroy_normal() { // Error #[test] -fn integration_test_db_create_error() { +fn transpile_integration_test_db_create_error() { // Generic Error Test assert!(engine("create database test").is_err()); assert!(engine("Create the test!").is_err()); @@ -45,7 +45,7 @@ fn integration_test_db_create_error() { } #[test] -fn integration_test_db_use_error() { +fn transpile_integration_test_db_use_error() { // Generic Error Test assert!(engine("use database test").is_err()); assert!(engine("Enter test!").is_err()); @@ -53,7 +53,7 @@ fn integration_test_db_use_error() { } #[test] -fn integration_test_db_show_error() { +fn transpile_integration_test_db_show_error() { // Generic Error Test assert!(engine("show database").is_err()); assert!(engine("show!").is_err()); @@ -61,7 +61,7 @@ fn integration_test_db_show_error() { } #[test] -fn integration_test_db_destroy_error() { +fn transpile_integration_test_db_destroy_error() { // Generic Error Test assert!(engine("delete databases db1, db2, db3").is_err()); assert!(engine("Delete db1!").is_err()); @@ -72,7 +72,7 @@ fn integration_test_db_destroy_error() { // Table Accessor Query Tests (Validator) // Normal #[test] -fn integration_test_table_accessor_normal_get() { +fn transpile_integration_test_table_accessor_normal_get() { // Test "wildcard" keywords assert_eq!(engine("get all from test_table;"), Ok("SELECT * FROM test_table;".to_string())); assert_eq!(engine("get any from test_table;"), Ok("SELECT * FROM test_table;".to_string())); @@ -89,7 +89,7 @@ fn integration_test_table_accessor_normal_get() { } #[test] -fn integration_test_table_accessor_normal_filter() { +fn transpile_integration_test_table_accessor_normal_filter() { // Test "filter entrance" keywords assert_eq!(engine("get all from test_table where id = 3;"), Ok("SELECT * FROM test_table WHERE id = 3;".to_string())); assert_eq!(engine("get all from test_table wherever id = 3;"), Ok("SELECT * FROM test_table WHERE id = 3;".to_string())); @@ -99,14 +99,14 @@ fn integration_test_table_accessor_normal_filter() { assert_eq!(engine("get all from test_table where id = 3 and price = 2.0."), Ok("SELECT * FROM test_table WHERE id = 3 and price = 2.0;".to_string())); assert_eq!(engine("get all from test_table where id = 3 or (price <= 2 and name is \"3\")!"), - Ok("SELECT * FROM test_table WHERE id = 3 or ( price <= 2 and name = \"3\" );".to_string())); + Ok("SELECT * FROM test_table WHERE id = 3 or (price <= 2 and name = \"3\");".to_string())); assert_eq!(engine("get all from test_table where (price < 3 or name is \"test\" and (id = 3 or (value < 4 and time >= 5)));"), - Ok("SELECT * FROM test_table WHERE ( price < 3 or name = \"test\" and ( id = 3 or ( value < 4 and time >= 5 ) ) );".to_string())); + Ok("SELECT * FROM test_table WHERE (price < 3 or name = \"test\" and (id = 3 or (value < 4 and time >= 5)));".to_string())); } #[test] -fn integration_test_table_accessor_normal_postprocessor() { +fn transpile_integration_test_table_accessor_normal_postprocessor() { // Test "post-processor entrance" keywords assert_eq!(engine("get all from test_table then limit 5;"), Ok("SELECT * FROM test_table LIMIT 5;".to_string())); assert_eq!(engine("get all from test_table afterwords limit 5;"), Ok("SELECT * FROM test_table LIMIT 5;".to_string())); @@ -114,12 +114,12 @@ fn integration_test_table_accessor_normal_postprocessor() { // Test post-processor w/ filter assert_eq!(engine("get all from test_table where id = 3 or (price <= 2 and name is \"3\") then limit 5."), - Ok("SELECT * FROM test_table WHERE id = 3 or ( price <= 2 and name = \"3\" ) LIMIT 5;".to_string())); + Ok("SELECT * FROM test_table WHERE id = 3 or (price <= 2 and name = \"3\") LIMIT 5;".to_string())); } #[test] -fn integration_test_table_accessor_normal_postprocessor_limit() { +fn transpile_integration_test_table_accessor_normal_postprocessor_limit() { // Test "post-processor limit" keywords assert_eq!(engine("get all from test_table then limit 5;"), Ok("SELECT * FROM test_table LIMIT 5;".to_string())); assert_eq!(engine("get all from test_table then limit it to 5;"), Ok("SELECT * FROM test_table LIMIT 5;".to_string())); @@ -127,7 +127,7 @@ fn integration_test_table_accessor_normal_postprocessor_limit() { // Error #[test] -fn integration_test_table_accessor_error_get() { +fn transpile_integration_test_table_accessor_error_get() { // Test improper tokens assert!(engine("get all from \"test_table\";").is_err()); assert!(engine("get all from test_table").is_err()); @@ -139,7 +139,7 @@ fn integration_test_table_accessor_error_get() { } #[test] -fn integration_test_table_accessor_error_filter() { +fn transpile_integration_test_table_accessor_error_filter() { // Test bad conditions assert!(engine("get all from test_table where id = 3").is_err()); assert!(engine("get all from test_table where id is equal to 3;").is_err()); @@ -152,7 +152,7 @@ fn integration_test_table_accessor_error_filter() { } #[test] -fn integration_test_table_accessor_error_postprocessor() { +fn transpile_integration_test_table_accessor_error_postprocessor() { // Generic tests assert!(engine("get all from test_table then limit 5").is_err()); @@ -164,7 +164,7 @@ fn integration_test_table_accessor_error_postprocessor() { } #[test] -fn integration_test_table_accessor_error_postprocessor_limit() { +fn transpile_integration_test_table_accessor_error_postprocessor_limit() { // Test bad limit assert!(engine("get all from test_table then limit = 5;").is_err()); assert!(engine("get all from test_table then limit id;").is_err()); diff --git a/tests/validator_tests.rs b/tests/validator_tests.rs index d699a53..15fb5d8 100644 --- a/tests/validator_tests.rs +++ b/tests/validator_tests.rs @@ -3,28 +3,28 @@ use eaql::validator::engine; // Database Query Tests (Validator) // Normal #[test] -fn integration_test_db_create_normal() { +fn validator_integration_test_db_create_normal() { // Create keyword tests assert_eq!(engine("create database test;"), true); assert_eq!(engine("make database test."), true); } #[test] -fn integration_test_db_use_normal() { +fn validator_integration_test_db_use_normal() { // Use keyword tests assert_eq!(engine("use database test;"), true); assert_eq!(engine("enter database test;"), true); } #[test] -fn integration_test_db_show_normal() { +fn validator_integration_test_db_show_normal() { // Show keyword tests assert_eq!(engine("show database;"), true); assert_eq!(engine("list databases."), true); } #[test] -fn integration_test_db_destroy_normal() { +fn validator_integration_test_db_destroy_normal() { // Destroy assert_eq!(engine("remove database db1!"), true); assert_eq!(engine("destroy database db1!"), true); @@ -37,7 +37,7 @@ fn integration_test_db_destroy_normal() { // Error #[test] -fn integration_test_db_create_error() { +fn validator_integration_test_db_create_error() { // Generic Error Test assert_eq!(engine("create database test"), false); assert_eq!(engine("Create the test!"), false); @@ -45,7 +45,7 @@ fn integration_test_db_create_error() { } #[test] -fn integration_test_db_use_error() { +fn validator_integration_test_db_use_error() { // Generic Error Test assert_eq!(engine("use database test"), false); assert_eq!(engine("Enter test!"), false); @@ -53,7 +53,7 @@ fn integration_test_db_use_error() { } #[test] -fn integration_test_db_show_error() { +fn validator_integration_test_db_show_error() { // Generic Error Test assert_eq!(engine("show database"), false); assert_eq!(engine("show!"), false); @@ -61,7 +61,7 @@ fn integration_test_db_show_error() { } #[test] -fn integration_test_db_destroy_error() { +fn validator_integration_test_db_destroy_error() { // Generic Error Test assert_eq!(engine("delete databases db1, db2, db3"), false); assert_eq!(engine("Delete db1!"), false); @@ -72,7 +72,7 @@ fn integration_test_db_destroy_error() { // Table Accessor Query Tests (Validator) // Normal #[test] -fn integration_test_table_accessor_normal_get() { +fn validator_integration_test_table_accessor_normal_get() { // Test "wildcard" keywords assert_eq!(engine("get all from test_table;"), true); assert_eq!(engine("get any from test_table;"), true); @@ -89,7 +89,7 @@ fn integration_test_table_accessor_normal_get() { } #[test] -fn integration_test_table_accessor_normal_filter() { +fn validator_integration_test_table_accessor_normal_filter() { // Test "filter entrance" keywords assert_eq!(engine("get all from test_table where id = 3;"), true); assert_eq!(engine("get all from test_table wherever id = 3;"), true); @@ -103,7 +103,7 @@ fn integration_test_table_accessor_normal_filter() { #[test] -fn integration_test_table_accessor_normal_postprocessor() { +fn validator_integration_test_table_accessor_normal_postprocessor() { // Test "post-processor entrance" keywords assert_eq!(engine("get all from test_table then limit 5;"), true); assert_eq!(engine("get all from test_table afterwords limit 5;"), true); @@ -115,7 +115,7 @@ fn integration_test_table_accessor_normal_postprocessor() { #[test] -fn integration_test_table_accessor_normal_postprocessor_limit() { +fn validator_integration_test_table_accessor_normal_postprocessor_limit() { // Test "post-processor limit" keywords assert_eq!(engine("get all from test_table then limit 5;"), true); assert_eq!(engine("get all from test_table then limit it to 5;"), true); @@ -123,7 +123,7 @@ fn integration_test_table_accessor_normal_postprocessor_limit() { // Error #[test] -fn integration_test_table_accessor_error_get() { +fn validator_integration_test_table_accessor_error_get() { // Test improper tokens assert_eq!(engine("get all from \"test_table\";"), false); assert_eq!(engine("get all from test_table"), false); @@ -135,7 +135,7 @@ fn integration_test_table_accessor_error_get() { } #[test] -fn integration_test_table_accessor_error_filter() { +fn validator_integration_test_table_accessor_error_filter() { // Test bad conditions assert_eq!(engine("get all from test_table where id = 3"), false); assert_eq!(engine("get all from test_table where id is equal to 3;"), false); @@ -148,7 +148,7 @@ fn integration_test_table_accessor_error_filter() { } #[test] -fn integration_test_table_accessor_error_postprocessor() { +fn validator_integration_test_table_accessor_error_postprocessor() { // Generic tests assert_eq!(engine("get all from test_table then limit 5"), false); @@ -160,7 +160,7 @@ fn integration_test_table_accessor_error_postprocessor() { } #[test] -fn integration_test_table_accessor_error_postprocessor_limit() { +fn validator_integration_test_table_accessor_error_postprocessor_limit() { // Test bad limit assert_eq!(engine("get all from test_table then limit = 5;"), false); assert_eq!(engine("get all from test_table then limit id;"), false);