diff --git a/internal/validator/validator.go b/internal/validator/validator.go index 43a1012..8f1babf 100644 --- a/internal/validator/validator.go +++ b/internal/validator/validator.go @@ -116,6 +116,27 @@ func checkMessageSubject(s *string) error { return nil } +/** + * checkMessageLength - Checks if the commit message is equal to or under 50 characters. + * + * This function ensures the commit message does not exceed 50 characters in length. + * + * Parameters: + * - l (*string): A pointer to the string representing the length + * of the commit message. + * Returns: + * - error: Returns an error if the commit message is more than 50 characters. + * Returns nil if the message is within the valid length + */ + +func checkMessageLength(l *string) error { + if len(*l) >= 50 { + return fmt.Errorf("commit message exceeds 50 characters, current length: %d", + len(*l)) + } + return nil +} + /** * ValidateMessage: Validate a "git-commit" message. * @@ -142,6 +163,11 @@ func ValidateMessage(message *parser.Message) (string, error) { return "", fmt.Errorf("%s", err) } + // Validate the commit message length + if err := checkMessageLength(&message.Description); err != nil { + return "", fmt.Errorf("%s", err) + } + // Return a success message if the commit message validation was successful return "valid commit message", nil } diff --git a/internal/validator/validator_test.go b/internal/validator/validator_test.go new file mode 100644 index 0000000..fecfb72 --- /dev/null +++ b/internal/validator/validator_test.go @@ -0,0 +1,256 @@ +package validator + +import ( + "fmt" + "testing" + + "github.com/Weburz/crisp/internal/parser" +) + +// TestCheckMessageType tests the checkMessageType function. +func TestCheckMessageType(t *testing.T) { + testCases := []struct { + name string + messageType string + expectedError string + }{ + { + name: "Valid Type - feat", + messageType: "feat", + expectedError: "", + }, + { + name: "Invalid Type - Uppercase", + messageType: "Feat", + expectedError: `invalid commit message casing, "Feat" should be "feat"`, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := checkMessageType(&tc.messageType) + if tc.expectedError == "" { + if err != nil { + t.Errorf("expected no error, got %v", err) + } + } else { + if err == nil || err.Error() != tc.expectedError { + t.Errorf("expected error %q, got %q", tc.expectedError, err) + } + } + }) + } +} + +// TestCheckMessageScope tests the checkMessageScope function. +func TestCheckMessageScope(t *testing.T) { + testCases := []struct { + name string + scope string + expectedError string + }{ + { + name: "Valid Scope - Lowercase", + scope: "user", + expectedError: "", + }, + { + name: "Valid Scope - Empty", + scope: "", + expectedError: "", + }, + { + name: "Invalid Scope - Uppercase", + scope: "User", + expectedError: `invalid commit message scope casing, "User" ` + + `should be "user"`}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := checkMessageScope(&tc.scope) + if tc.expectedError == "" { + if err != nil { + t.Errorf("expected no error, got %v", err) + } + } else { + if err == nil || err.Error() != tc.expectedError { + t.Errorf("expected error %q, got %q", tc.expectedError, err) + } + } + }) + } +} + +// TestCheckMessageSubject tests the checkMessageSubject function. +func TestCheckMessageSubject(t *testing.T) { + testCases := []struct { + name string + subject string + expectedError string + }{ + { + name: "Valid Subject - Lowercase", + subject: "add a new feature", + expectedError: "", + }, + { + name: "Invalid Subject - Uppercase", + subject: "Add a new feature", + expectedError: "commit message subject should be lowercased & " + + "not end with a period(.)", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := checkMessageSubject(&tc.subject) + if tc.expectedError == "" { + if err != nil { + t.Errorf("expected no error, got %v", err) + } + } else { + if err == nil || err.Error() != tc.expectedError { + t.Errorf("expected error %q, got %q", tc.expectedError, err) + } + } + }) + } +} + +// TestCheckMessageLength tests the checkMessageLength function. +func TestCheckMessageLength(t *testing.T) { + testCases := []struct { + name string + message string + expectedError string + }{ + { + name: "Valid Length", + message: "feat: add a new feature", + expectedError: "", + }, + { + name: "Invalid Length", + message: "Add a new feature that makes the application run " + + "faster and more efficiently", + expectedError: fmt.Sprintf( + "commit message exceeds 50 characters, current length: %d", + len("Add a new feature that makes the application run "+ + "faster and more efficiently"), + ), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := checkMessageLength(&tc.message) + if tc.expectedError == "" { + if err != nil { + t.Errorf("expected no error, got %v", err) + } + } else { + if err == nil || err.Error() != tc.expectedError { + t.Errorf("expected error %q, got %q", tc.expectedError, err) + } + } + }) + } +} + +// TestValidateMessage tests the ValidateMessage function. +func TestValidateMessage(t *testing.T) { + testCases := []struct { + name string + message parser.Message + expectedError string + expectedMessage string + }{ + { + name: "Valid Message", + message: parser.Message{ + Type: "feat", + Scope: "user", + Description: "add a new feature", + }, + expectedError: "", + expectedMessage: "valid commit message", + }, + { + name: "Invalid Message - Invalid Type", + message: parser.Message{ + Type: "Invalid", + Scope: "user", + Description: "add a new feature", + }, + expectedError: `invalid commit message type: Invalid`, + expectedMessage: "", + }, + { + name: "Invalid Message - Invalid Scope", + message: parser.Message{ + Type: "feat", + Scope: "User", + Description: "add a new feature", + }, + expectedError: `invalid commit message scope casing, "User" ` + + `should be "user"`, + expectedMessage: "", + }, + { + name: "Invalid Message - Invalid Subject", + message: parser.Message{ + Type: "feat", + Scope: "user", + Description: "Add a new feature", + }, + expectedError: "commit message subject should be lowercased & " + + "not end with a period(.)", + expectedMessage: "", + }, + { + name: "Invalid Message - Exceeds Length", + message: parser.Message{ + Type: "feat", + Scope: "user", + Description: "add a new feature that makes the application run " + + "faster and more efficiently", + }, + expectedError: fmt.Sprintf( + "commit message exceeds 50 characters, current length: %d", + len("Add a new feature that makes the application run "+ + "faster and more efficiently"), + ), + expectedMessage: "", + }, + { + name: "Valid Message - Empty Scope", + message: parser.Message{ + Type: "feat", + Scope: "", + Description: "add a new feature", + }, + expectedError: "", + expectedMessage: "valid commit message", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + messageResult, err := ValidateMessage(&tc.message) + + if tc.expectedError == "" && err != nil { + t.Errorf("expected no error, got %v", err) + } else if err != nil && err.Error() != tc.expectedError { + t.Errorf("expected error %q, got %q", + tc.expectedError, err.Error()) + } + + if messageResult != tc.expectedMessage { + t.Errorf("expected message %q, got %q", + tc.expectedMessage, messageResult, + ) + } + }) + } +}