@@ -377,227 +377,76 @@ def test_commit_command_with_config_message_length_limit(
377377
378378
379379@pytest .mark .usefixtures ("staging_is_clean" )
380- def test_commit_command_with_body_length_limit_wrapping (
381- config , success_mock : MockType , mocker : MockFixture
382- ):
383- """Test that long body lines are automatically wrapped to the specified limit."""
384- mocker .patch (
385- "questionary.prompt" ,
386- return_value = {
387- "prefix" : "feat" ,
388- "subject" : "add feature" ,
389- "scope" : "" ,
390- "is_breaking_change" : False ,
391- "body" : "This is a very long line that exceeds 72 characters and should be automatically wrapped by the system to fit within the limit" ,
392- "footer" : "" ,
393- },
394- )
395-
396- commit_mock = mocker .patch (
397- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
398- )
399-
400- # Execute with body_length_limit
401- commands .Commit (config , {"body_length_limit" : 72 })()
402- success_mock .assert_called_once ()
403-
404- # Verify wrapping occurred
405- committed_message = commit_mock .call_args [0 ][0 ]
406- lines = committed_message .split ("\n " )
407- assert lines [0 ] == "feat: add feature"
408- assert lines [1 ] == ""
409- body_lines = lines [2 :]
410- for line in body_lines :
411- if line .strip ():
412- assert len (line ) <= 72 , (
413- f"Line exceeds 72 chars: '{ line } ' ({ len (line )} chars)"
414- )
415-
416-
417- @pytest .mark .usefixtures ("staging_is_clean" )
418- def test_commit_command_with_body_length_limit_preserves_line_breaks (
419- config , success_mock : MockType , mocker : MockFixture
420- ):
421- """Test that intentional line breaks (from | character) are preserved."""
422- # Simulate what happens after multiple_line_breaker processes "line1 | line2 | line3"
423- mocker .patch (
424- "questionary.prompt" ,
425- return_value = {
426- "prefix" : "feat" ,
427- "subject" : "add feature" ,
428- "scope" : "" ,
429- "is_breaking_change" : False ,
430- "body" : "Line1 that is very long and exceeds the limit\n Line2 that is very long and exceeds the limit\n Line3 that is very long and exceeds the limit" ,
431- "footer" : "" ,
432- },
433- )
434-
435- commit_mock = mocker .patch (
436- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
437- )
438-
439- commands .Commit (config , {"body_length_limit" : 45 })()
440- success_mock .assert_called_once ()
441-
442- committed_message = commit_mock .call_args [0 ][0 ]
443- lines = committed_message .split ("\n " )
444-
445- # Should have a subject, a blank line
446- assert lines [0 ] == "feat: add feature"
447- assert lines [1 ] == ""
448- # Each original line should be wrapped separately, preserving the line breaks
449- body_lines = lines [2 :]
450- # All lines should be <= 45 chars
451- for line in body_lines :
452- if line .strip ():
453- assert len (line ) == 45 , (
454- f"Line's length is not 45 chars: '{ line } ' ({ len (line )} chars)"
455- )
456-
457-
458- @pytest .mark .usefixtures ("staging_is_clean" )
459- def test_commit_command_with_body_length_limit_disabled (
460- config , success_mock : MockType , mocker : MockFixture
461- ):
462- """Test that body_length_limit = 0 disables wrapping."""
463- long_body = "This is a very long line that exceeds 72 characters and should NOT be wrapped when body_length_limit is set to 0"
464-
465- mocker .patch (
466- "questionary.prompt" ,
467- return_value = {
468- "prefix" : "feat" ,
469- "subject" : "add feature" ,
470- "scope" : "" ,
471- "is_breaking_change" : False ,
472- "body" : long_body ,
473- "footer" : "" ,
474- },
475- )
476-
477- commit_mock = mocker .patch (
478- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
479- )
480-
481- # Execute with body_length_limit = 0 (disabled)
482- commands .Commit (config , {"body_length_limit" : 0 })()
483-
484- success_mock .assert_called_once ()
485-
486- # Get the actual commit message
487- committed_message = commit_mock .call_args [0 ][0 ]
488-
489- # Verify the body was NOT wrapped (should contain the original long line)
490- assert long_body in committed_message , "Body should not be wrapped when limit is 0"
491-
492-
493- @pytest .mark .usefixtures ("staging_is_clean" )
494- def test_commit_command_with_body_length_limit_from_config (
495- config , success_mock : MockType , mocker : MockFixture
380+ @pytest .mark .parametrize (
381+ "test_id,body,body_length_limit" ,
382+ [
383+ # Basic wrapping - long line gets wrapped
384+ (
385+ "wrapping" ,
386+ "This is a very long line that exceeds 72 characters and should be automatically wrapped by the system to fit within the limit" ,
387+ 72 ,
388+ ),
389+ # Line break preservation - multiple lines with \n
390+ (
391+ "preserves_line_breaks" ,
392+ "Line1 that is very long and exceeds the limit\n Line2 that is very long and exceeds the limit\n Line3 that is very long and exceeds the limit" ,
393+ 72 ,
394+ ),
395+ # Disabled wrapping - limit = 0
396+ (
397+ "disabled" ,
398+ "This is a very long line that exceeds 72 characters and should NOT be wrapped when body_length_limit is set to 0" ,
399+ 0 ,
400+ ),
401+ # No body - empty string
402+ (
403+ "no_body" ,
404+ "" ,
405+ 72 ,
406+ ),
407+ ],
408+ )
409+ def test_commit_command_body_length_limit (
410+ test_id ,
411+ body ,
412+ body_length_limit ,
413+ config ,
414+ success_mock : MockType ,
415+ commit_mock ,
416+ mocker : MockFixture ,
417+ file_regression ,
496418):
497- """Test that body_length_limit can be set via config ."""
419+ """Parameterized test for body_length_limit feature with file regression ."""
498420 mocker .patch (
499421 "questionary.prompt" ,
500422 return_value = {
501423 "prefix" : "feat" ,
502424 "subject" : "add feature" ,
503425 "scope" : "" ,
504426 "is_breaking_change" : False ,
505- "body" : "This is a very long line that exceeds 50 characters and should be wrapped" ,
427+ "body" : body ,
506428 "footer" : "" ,
507429 },
508430 )
509431
510- commit_mock = mocker .patch (
511- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
512- )
513-
514- # Set body_length_limit in config
515- config .settings ["body_length_limit" ] = 50
516-
432+ config .settings ["body_length_limit" ] = body_length_limit
517433 commands .Commit (config , {})()
518434
519435 success_mock .assert_called_once ()
520-
521- # Get the actual commit message
522436 committed_message = commit_mock .call_args [0 ][0 ]
523437
524- # Verify all body lines are within the limit
525- lines = committed_message .split ("\n " )
526- body_lines = lines [2 :]
527- for line in body_lines :
528- if line .strip ():
529- assert len (line ) <= 50 , (
530- f"Line exceeds 50 chars: '{ line } ' ({ len (line )} chars)"
531- )
532-
533-
534- @pytest .mark .usefixtures ("staging_is_clean" )
535- def test_commit_command_body_length_limit_cli_overrides_config (
536- config , success_mock : MockType , mocker : MockFixture
537- ):
538- """Test that CLI argument overrides config setting."""
539- mocker .patch (
540- "questionary.prompt" ,
541- return_value = {
542- "prefix" : "feat" ,
543- "subject" : "add feature" ,
544- "scope" : "" ,
545- "is_breaking_change" : False ,
546- "body" : "This is a line that is longer than 40 characters but shorter than 80 characters" ,
547- "footer" : "" ,
548- },
438+ # File regression check - uses test_id to create separate files
439+ file_regression .check (
440+ committed_message ,
441+ extension = ".txt" ,
442+ basename = f"test_commit_command_body_length_limit_{ test_id } " ,
549443 )
550444
551- commit_mock = mocker .patch (
552- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
553- )
554-
555- # Set config to 40 (would wrap)
556- config .settings ["body_length_limit" ] = 40
557-
558- # Override with CLI argument to 0 (should NOT wrap)
559- commands .Commit (config , {"body_length_limit" : 0 })()
560-
561- success_mock .assert_called_once ()
562-
563- # Get the actual commit message
564- committed_message = commit_mock .call_args [0 ][0 ]
565-
566- # The line should NOT be wrapped (CLI override to 0 disables wrapping)
567- assert (
568- "This is a line that is longer than 40 characters but shorter than 80 characters"
569- in committed_message
570- )
571-
572-
573- @pytest .mark .usefixtures ("staging_is_clean" )
574- def test_commit_command_with_body_length_limit_no_body (
575- config , success_mock : MockType , mocker : MockFixture
576- ):
577- """Test that commits without body work correctly with body_length_limit set."""
578- mocker .patch (
579- "questionary.prompt" ,
580- return_value = {
581- "prefix" : "feat" ,
582- "subject" : "add feature" ,
583- "scope" : "" ,
584- "is_breaking_change" : False ,
585- "body" : "" , # No body
586- "footer" : "" ,
587- },
588- )
589-
590- commit_mock = mocker .patch (
591- "commitizen.git.commit" , return_value = cmd .Command ("success" , "" , b"" , b"" , 0 )
592- )
593-
594- # Execute commit with body_length_limit (should not crash)
595- commands .Commit (config , {"body_length_limit" : 72 })()
596-
597- success_mock .assert_called_once ()
598-
599- # Get the actual commit message
600- committed_message = commit_mock .call_args [0 ][0 ]
601-
602- # Should just be the subject line
603- assert committed_message .strip () == "feat: add feature"
445+ # Validate line lengths if limit is not 0
446+ if body_length_limit > 0 :
447+ lines = committed_message .split ("\n " )
448+ body_lines = lines [2 :] # Skip subject and blank line
449+ for line in body_lines :
450+ assert len (line ) <= body_length_limit , (
451+ f"Line exceeds { body_length_limit } chars: '{ line } ' ({ len (line )} chars)"
452+ )
0 commit comments