From 147fbe9eb402b14e2a492c85ac7814c89ffa6068 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:42:47 -0300 Subject: [PATCH 01/11] update test code folder name --- tests/{sample_files => sample-code}/example.go | 0 tests/{sample_files => sample-code}/example.js | 0 tests/{sample_files => sample-code}/example.py | 0 tests/{sample_files => sample-code}/example.rb | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/{sample_files => sample-code}/example.go (100%) rename tests/{sample_files => sample-code}/example.js (100%) rename tests/{sample_files => sample-code}/example.py (100%) rename tests/{sample_files => sample-code}/example.rb (100%) 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 From 619b56af9ea892346d026fd45dc82cc047e9d4e1 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:45:16 -0300 Subject: [PATCH 02/11] remove broken tests --- tests/unit/__init__.py | 0 tests/unit/test_analyze.py | 49 -------------------------------------- 2 files changed, 49 deletions(-) delete mode 100644 tests/unit/__init__.py delete mode 100644 tests/unit/test_analyze.py 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 From 01fad5b343af4e09033613af8461b466a826e1f1 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:49:01 -0300 Subject: [PATCH 03/11] add pytest to dependencies list --- requirements.txt | Bin 268 -> 298 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 08d6a8a5f66389a91fed666bcbd281e38530d709..28be2e00e28d2ce201a582b2886986d5ac363fb2 100644 GIT binary patch delta 38 ocmeBSTE(=1hf$7~fs3Jlp^~A5A(f#RNZK*jGMF>yF&Ka`0FbH%L;wH) delta 7 OcmZ3*)WfuahY From 092e12c8297d330e4ad46e5e7171126415e9b889 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:49:24 -0300 Subject: [PATCH 04/11] create test to test analyze command with --json flag analyzing the python sample code --- .../test_analyze_json_python-example.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/analyze/test_analyze_json_python-example.py 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..02eafd2 --- /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 "filename" 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["filename"] == 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 From 47c5bfd9a75ec224ce8322f31070db622e86e6e1 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:52:19 -0300 Subject: [PATCH 05/11] fix json output skipping lines --- cli/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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}") From a6c3756f2dcf60de0225314e304781034d33a30f Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:52:39 -0300 Subject: [PATCH 06/11] fix sample file path --- tests/analyze/test_analyze_json_python-example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/analyze/test_analyze_json_python-example.py b/tests/analyze/test_analyze_json_python-example.py index 02eafd2..acf09ab 100644 --- a/tests/analyze/test_analyze_json_python-example.py +++ b/tests/analyze/test_analyze_json_python-example.py @@ -8,7 +8,7 @@ runner = CliRunner() # Get the absolute path to the sample file -SAMPLE_FILE_PATH = os.path.join(os.path.dirname(__file__), "sample-code", "example.py") +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""" From 5ed59beac92b30f847586aff0c0dd72a71fc3856 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:52:58 -0300 Subject: [PATCH 07/11] fix file_name typo --- tests/analyze/test_analyze_json_python-example.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/analyze/test_analyze_json_python-example.py b/tests/analyze/test_analyze_json_python-example.py index acf09ab..267106d 100644 --- a/tests/analyze/test_analyze_json_python-example.py +++ b/tests/analyze/test_analyze_json_python-example.py @@ -22,13 +22,13 @@ def test_analyze_command_with_json_flag(): output = json.loads(result.stdout) # Check if all expected stats are in the output - assert "filename" in 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["filename"] == SAMPLE_FILE_PATH + assert output["file_name"] == SAMPLE_FILE_PATH assert output["line_count"] == 161 assert output["comment_line_count"] == 25 assert output["function_count"] == 17 From 6c971103d1fea521eb1fff84be0dde85c71b5161 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:57:13 -0300 Subject: [PATCH 08/11] fix count_comment_lines to actually do what it's intended for and pass the test wow TDD is so cool --- spice/analyze.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/spice/analyze.py b/spice/analyze.py index 60d4623..2de3dd2 100644 --- a/spice/analyze.py +++ b/spice/analyze.py @@ -137,11 +137,25 @@ 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 +# 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(tokens): comment_count = 0 - + line_number = 1 + comment_lines = set() + for token in tokens: + # track line number across all tokens + line_number += token.value.count('\n') + if token.type == TokenType.COMMENT: - comment_count += 1 + # only count if this is the first non-whitespace token on its line + # get the line this token starts on + token_line = line_number - token.value.count('\n') + + # check if we already encountered a non-comment token on this line + if token_line not in comment_lines: + comment_count += 1 + comment_lines.add(token_line) return comment_count \ No newline at end of file From 47e6d3b91513b32317a7b64787399a6ea68e1ceb Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 21:57:54 -0300 Subject: [PATCH 09/11] fix count_comment_lines --- spice/analyze.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/spice/analyze.py b/spice/analyze.py index 2de3dd2..ae4e232 100644 --- a/spice/analyze.py +++ b/spice/analyze.py @@ -139,23 +139,16 @@ 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 # 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(tokens): +def count_comment_lines(code): + """Count lines that are exclusively comments (no code on the same line)""" + lines = code.split('\n') comment_count = 0 - line_number = 1 - comment_lines = set() - for token in tokens: - # track line number across all tokens - line_number += token.value.count('\n') - - if token.type == TokenType.COMMENT: - # only count if this is the first non-whitespace token on its line - # get the line this token starts on - token_line = line_number - token.value.count('\n') - - # check if we already encountered a non-comment token on this line - if token_line not in comment_lines: - comment_count += 1 - comment_lines.add(token_line) + 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 From 2ea1851fb58318fcc9111f74620ec292c9f921f9 Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 22:04:48 -0300 Subject: [PATCH 10/11] fix comment line counter --- spice/analyze.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spice/analyze.py b/spice/analyze.py index ae4e232..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: @@ -141,13 +141,14 @@ def search_node(node): # 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)""" - lines = code.split('\n') + # split the code into lines + lines = code.splitlines() comment_count = 0 for line in lines: - # remove leading whitespace + # Remove leading whitespace stripped = line.strip() - # check if this line consists only of a comment + # Check if this line consists only of a comment if stripped and stripped.startswith('#'): comment_count += 1 From f7e207e400f1fd93545ec4a85aefa1848529671e Mon Sep 17 00:00:00 2001 From: CodyKoInABox Date: Tue, 11 Mar 2025 22:06:59 -0300 Subject: [PATCH 11/11] fix filename assert to expect filename and not full path --- tests/analyze/test_analyze_json_python-example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/analyze/test_analyze_json_python-example.py b/tests/analyze/test_analyze_json_python-example.py index 267106d..10e501a 100644 --- a/tests/analyze/test_analyze_json_python-example.py +++ b/tests/analyze/test_analyze_json_python-example.py @@ -28,7 +28,7 @@ def test_analyze_command_with_json_flag(): assert "function_count" in output # Verify the values match expected results - assert output["file_name"] == SAMPLE_FILE_PATH + 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