diff --git a/cli/main.py b/cli/main.py index dd986c4..834ce8b 100644 --- a/cli/main.py +++ b/cli/main.py @@ -224,7 +224,9 @@ def analyze( except Exception as e: if json_output: import json - print(json.dumps({"error": str(e)})) + # Replace newlines with spaces or escape them properly + error_msg = str(e).replace('\n', ' ') + print(json.dumps({"error": error_msg})) else: print(f"[red]{messages['error']}[/] {e}") diff --git a/requirements.txt b/requirements.txt index 08d6a8a..28be2e0 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/spice/analyze.py b/spice/analyze.py index 60d4623..7a1e3e7 100644 --- a/spice/analyze.py +++ b/spice/analyze.py @@ -66,7 +66,7 @@ def analyze_file(file_path: str, selected_stats=None): # process comment line count if requested if "comment_line_count" in selected_stats: - results["comment_line_count"] = count_comment_lines(tokens) + results["comment_line_count"] = count_comment_lines(code) # only put the code through the parser and proceed with parsing if we need function count (UPDATE THIS WHEN NEEDED PLEASE !!!!!!!!) if "function_count" in selected_stats: @@ -137,11 +137,19 @@ def search_node(node): # this will count comment lines, since our AST/Parser doesn't include comment lines, this needs to be done in the tokenized output of the lexer -def count_comment_lines(tokens): +# COMMENT LINE IS A LINE THAT EXCLUSIVELY HAS A COMMENT +# so like: y = 5 #sets y to 5 IS NOT A COMMENT LINE!!!!!!!! +def count_comment_lines(code): + """Count lines that are exclusively comments (no code on the same line)""" + # split the code into lines + lines = code.splitlines() comment_count = 0 - - for token in tokens: - if token.type == TokenType.COMMENT: + + for line in lines: + # Remove leading whitespace + stripped = line.strip() + # Check if this line consists only of a comment + if stripped and stripped.startswith('#'): comment_count += 1 return comment_count \ No newline at end of file diff --git a/tests/analyze/test_analyze_json_python-example.py b/tests/analyze/test_analyze_json_python-example.py new file mode 100644 index 0000000..10e501a --- /dev/null +++ b/tests/analyze/test_analyze_json_python-example.py @@ -0,0 +1,61 @@ +import json +import os +import pytest +from typer.testing import CliRunner +from cli.main import app + +# Setup test runner +runner = CliRunner() + +# Get the absolute path to the sample file +SAMPLE_FILE_PATH = os.path.join(os.path.dirname(__file__), "..", "sample-code", "example.py") + +def test_analyze_command_with_json_flag(): + """Test the analyze command with the --json flag""" + # Run the command with --json flag + result = runner.invoke(app, ["analyze", SAMPLE_FILE_PATH, "--json"]) + + # Check if the command executed successfully + assert result.exit_code == 0 + + # Parse the JSON output + output = json.loads(result.stdout) + + # Check if all expected stats are in the output + assert "file_name" in output + assert "line_count" in output + assert "comment_line_count" in output + assert "function_count" in output + + # Verify the values match expected results + assert output["file_name"] == os.path.basename(SAMPLE_FILE_PATH) + assert output["line_count"] == 161 + assert output["comment_line_count"] == 25 + assert output["function_count"] == 17 + +def test_analyze_command_with_all_and_json_flags(): + """Test the analyze command with both --all and --json flags""" + # Run the command with both flags + result = runner.invoke(app, ["analyze", SAMPLE_FILE_PATH, "--all", "--json"]) + + # Check if the command executed successfully + assert result.exit_code == 0 + + # Parse the JSON output + output = json.loads(result.stdout) + + # Verify the values match expected results + assert output["line_count"] == 161 + assert output["comment_line_count"] == 25 + assert output["function_count"] == 17 + +def test_analyze_command_with_nonexistent_file(): + """Test the analyze command with a nonexistent file""" + # Run the command with a file that doesn't exist + result = runner.invoke(app, ["analyze", "nonexistent_file.py", "--json"]) + + # Parse the JSON output (should contain an error) + output = json.loads(result.stdout) + + # Check if the output contains an error message + assert "error" in output \ No newline at end of file diff --git a/tests/sample_files/example.go b/tests/sample-code/example.go similarity index 100% rename from tests/sample_files/example.go rename to tests/sample-code/example.go diff --git a/tests/sample_files/example.js b/tests/sample-code/example.js similarity index 100% rename from tests/sample_files/example.js rename to tests/sample-code/example.js diff --git a/tests/sample_files/example.py b/tests/sample-code/example.py similarity index 100% rename from tests/sample_files/example.py rename to tests/sample-code/example.py diff --git a/tests/sample_files/example.rb b/tests/sample-code/example.rb similarity index 100% rename from tests/sample_files/example.rb rename to tests/sample-code/example.rb diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/test_analyze.py b/tests/unit/test_analyze.py deleted file mode 100644 index 4cd0efa..0000000 --- a/tests/unit/test_analyze.py +++ /dev/null @@ -1,49 +0,0 @@ -import os -import unittest -from spice.analyze import analyze_file - -class TestAnalyze(unittest.TestCase): - def setUp(self): - # caminho para a pasta de arquivos de exemplo - self.sample_files = os.path.join(os.path.dirname(__file__), "sample_files") - - - def test_count_lines(self): - # testa a contagem de linhas para um arquivo Python - file_path = os.path.join(self.sample_files, "example.py") - results = analyze_file(file_path, selected_stats=["line_count"]) - self.assertEqual(results["line_count"], 161) - - def test_count_functions_python(self): - # testa a contagem de funções para um arquivo Python - file_path = os.path.join(self.sample_files, "example.py") - results = analyze_file(file_path, selected_stats=["function_count"]) - self.assertEqual(results["function_count"], 17) - - def test_count_functions_javascript(self): - # testa a contagem de funções para um arquivo JavaScript - file_path = os.path.join(self.sample_files, "example.js") - results = analyze_file(file_path, selected_stats=["function_count"]) - self.assertEqual(results["function_count"], 153) - def test_count_comment_lines_ruby(self): - # testa a contagem de linhas de comentário para um arquivo Ruby - file_path = os.path.join(self.sample_files, "example.rb") - results = analyze_file(file_path, selected_stats=["comment_line_count"]) - self.assertEqual(results["comment_line_count"], 226) - - def test_count_comment_lines_go(self): - # testa a contagem de linhas de comentário para um arquivo Go - file_path = os.path.join(self.sample_files, "example.go") - results = analyze_file(file_path, selected_stats=["comment_line_count"]) - self.assertEqual(results["comment_line_count"], 195) - - def test_all_stats(self): - # testa a análise completa (todas as estatísticas) para um arquivo Python - file_path = os.path.join(self.sample_files, "example.py") - results = analyze_file(file_path) - self.assertIn("line_count", results) - self.assertIn("function_count", results) - self.assertIn("comment_line_count", results) - -if __name__ == "__main__": - unittest.main() \ No newline at end of file