From 59c8ca43ba6898f3cdce007cd0b3d489cc5b2094 Mon Sep 17 00:00:00 2001 From: r-sharp Date: Tue, 5 May 2026 12:57:17 +0100 Subject: [PATCH 1/2] adding check for one statement per line --- .../tests/test_umdp3_rules_S3.py | 59 +++++++++++++++++++ script_umdp3_checker/umdp3_rules_S3.py | 24 ++++++++ 2 files changed, 83 insertions(+) diff --git a/script_umdp3_checker/tests/test_umdp3_rules_S3.py b/script_umdp3_checker/tests/test_umdp3_rules_S3.py index 495f7a61..f481b98f 100644 --- a/script_umdp3_checker/tests/test_umdp3_rules_S3.py +++ b/script_umdp3_checker/tests/test_umdp3_rules_S3.py @@ -17,6 +17,7 @@ r3_1_1_there_can_be_only_one, r3_2_1_check_crown_copyright, r3_3_2_line_too_long, + r3_3_3_one_statement_per_line, r3_4_1_capitalised_keywords, r3_4_2_no_full_uppercase_variable_names, ) @@ -299,6 +300,64 @@ def test_r3_3_2_line_too_long( # ================================================================= +@pytest.mark.parametrize( + "changes_list, expected_result, expected_errors", + [ + ( + [["add", 74, ["icode=0 ; icode= icode + 1"]]], + 1, + {"multiple statements on one line": [74]}, + ), + ( + [ + [ + "add", + 83, + [ + "IF ( l_unscale ) THEN ; icode=-300 ; ALLOCATE(field( 1,1 ) ) ;" + + " END IF" + ], + ], + [ + "replace", + 116, + ["IF ( l_unscale ) THEN ; DEALLOCATE(field) ; END IF"], + ], + ], + 2, + {"multiple statements on one line": [83, 117]}, + ), + ( + [], + 0, + {}, + ), # No changes, expect no errors + ], + ids=[ + "single multi-statements failure", + "multiple multi-statments failure", + "No error check", + ], +) +def test_3_3_3_one_statement_per_line( + example_fortran_lines, changes_list, expected_result, expected_errors +): + modified_fortran_lines = modify_fortran_lines(example_fortran_lines, changes_list) + result = r3_3_3_one_statement_per_line(modified_fortran_lines) + failure_count = result.failure_count + errors = result.errors + for error, lines_list in errors.items(): + assert error in expected_errors + for line_no in lines_list: + assert line_no in expected_errors[error] + assert len(lines_list) == len(expected_errors[error]) + assert len(errors) == len(expected_errors) + assert failure_count == expected_result + + +# ================================================================= + + @pytest.mark.parametrize( "changes_list, expected_result, expected_errors", [ diff --git a/script_umdp3_checker/umdp3_rules_S3.py b/script_umdp3_checker/umdp3_rules_S3.py index b7f03dfa..16563633 100644 --- a/script_umdp3_checker/umdp3_rules_S3.py +++ b/script_umdp3_checker/umdp3_rules_S3.py @@ -267,6 +267,29 @@ def r3_3_2_line_too_long(lines: List[str]) -> TestResult: """ * TODO: Never put more than one statement on a line. +""" +def r3_3_3_one_statement_per_line(lines: List[str]) -> TestResult: + """Check for more than one statement on a line, by looking for the presence of a ";" character outside of quoted strings and comments.""" + failures = 0 + error_log = {} + count = -1 + for count, line in enumerate(lines, 1): + # Remove quoted strings and comments + if line.lstrip(" ").startswith("!"): + continue + clean_line = remove_quoted(line) + clean_line = remove_comments(clean_line) + if ";" in clean_line: + failures += 1 + error_log = add_error_log(error_log, "multiple statements on one line", count) + return TestResult( + checker_name="Test 3.3 One Statement Per Line", + failure_count=failures, + passed=(failures == 0), + output=f"Checked {count + 1} lines, found {failures} failures.", + errors=error_log, + ) +""" * TODO: Write your program in UK English, unless you have a very good reason for not doing so.""" """3.4 Fortran style @@ -431,6 +454,7 @@ def r3_4_2_no_full_uppercase_variable_names(lines: List[str]) -> TestResult: r3_1_1_there_can_be_only_one, r3_2_1_check_crown_copyright, r3_3_2_line_too_long, + r3_3_3_one_statement_per_line, r3_4_1_capitalised_keywords, r3_4_2_no_full_uppercase_variable_names, ] From c0f2330838a17bd96997f3195b8c165d941088f7 Mon Sep 17 00:00:00 2001 From: r-sharp Date: Tue, 5 May 2026 14:39:39 +0100 Subject: [PATCH 2/2] ruff ruffling feathers and complaining one commit too late. --- script_umdp3_checker/umdp3_rules_S3.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/script_umdp3_checker/umdp3_rules_S3.py b/script_umdp3_checker/umdp3_rules_S3.py index 16563633..7325f943 100644 --- a/script_umdp3_checker/umdp3_rules_S3.py +++ b/script_umdp3_checker/umdp3_rules_S3.py @@ -268,6 +268,8 @@ def r3_3_2_line_too_long(lines: List[str]) -> TestResult: """ * TODO: Never put more than one statement on a line. """ + + def r3_3_3_one_statement_per_line(lines: List[str]) -> TestResult: """Check for more than one statement on a line, by looking for the presence of a ";" character outside of quoted strings and comments.""" failures = 0 @@ -281,7 +283,9 @@ def r3_3_3_one_statement_per_line(lines: List[str]) -> TestResult: clean_line = remove_comments(clean_line) if ";" in clean_line: failures += 1 - error_log = add_error_log(error_log, "multiple statements on one line", count) + error_log = add_error_log( + error_log, "multiple statements on one line", count + ) return TestResult( checker_name="Test 3.3 One Statement Per Line", failure_count=failures, @@ -289,6 +293,8 @@ def r3_3_3_one_statement_per_line(lines: List[str]) -> TestResult: output=f"Checked {count + 1} lines, found {failures} failures.", errors=error_log, ) + + """ * TODO: Write your program in UK English, unless you have a very good reason for not doing so."""