github.com/blend/go-sdk@v1.20240719.1/assert/failure.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package assert
     9  
    10  import (
    11  	"encoding/json"
    12  	"fmt"
    13  	"strings"
    14  )
    15  
    16  // NewFailure creates a new failure.
    17  func NewFailure(message string, userMessageComponents ...interface{}) Failure {
    18  	return Failure{
    19  		Message:     message,
    20  		UserMessage: fmt.Sprint(userMessageComponents...),
    21  		CallerInfo:  callerInfoStrings(callerInfo()),
    22  	}
    23  }
    24  
    25  // Failure is an assertion failure.
    26  type Failure struct {
    27  	Message     string   `json:"message"`
    28  	UserMessage string   `json:"userMessage,omitempty"`
    29  	CallerInfo  []string `json:"callerInfo"`
    30  }
    31  
    32  // Error implements error.
    33  func (f Failure) Error() string {
    34  	return f.Message
    35  }
    36  
    37  // Text returns the text format of the failure.
    38  func (f Failure) Text() string {
    39  	errorTrace := strings.Join(f.CallerInfo, "\n\t")
    40  	if len(errorTrace) == 0 {
    41  		errorTrace = "Unknown"
    42  	}
    43  	assertionFailedLabel := color("Assertion Failed!", RED)
    44  	locationLabel := color("Assert Location", GRAY)
    45  	assertionLabel := color("Assertion", GRAY)
    46  	messageLabel := color("Message", GRAY)
    47  	if f.UserMessage != "" {
    48  		errorFormat := "%s\n%s\n%s:\n\t%s\n%s:\n\t%s\n%s:\n\t%s\n\n"
    49  		return fmt.Sprintf(errorFormat, "", assertionFailedLabel, locationLabel, errorTrace, assertionLabel, f.Message, messageLabel, f.UserMessage)
    50  	}
    51  	errorFormat := "%s\n%s\n%s:\n\t%s\n%s:\n\t%s\n\n"
    52  	return fmt.Sprintf(errorFormat, "", assertionFailedLabel, locationLabel, errorTrace, assertionLabel, f.Message)
    53  }
    54  
    55  // JSON returns the json format of the failure.
    56  func (f Failure) JSON() string {
    57  	contents, _ := json.Marshal(f)
    58  	return string(contents)
    59  }
    60  
    61  // TestString returns a plain text representation of the contents of a Failure, suitable for easy comparison within unit tests.
    62  // Only the first line of `Failure.CallerInfo` is included, if present, as an assertion of the entire call stack would be extremely verbose,
    63  // brittle, and offer little value.
    64  func (f Failure) TestString() string {
    65  	// this separator is unlikely to naturally occur in the formatted components, which aides the caller to disambiguate the failure internal state.
    66  	const separator = ";-- "
    67  	var res = f.Message
    68  	if f.UserMessage != "" {
    69  		if res == "" {
    70  			res = f.UserMessage
    71  		} else {
    72  			res = res + separator + f.UserMessage
    73  		}
    74  	}
    75  	if len(f.CallerInfo) >= 1 {
    76  		if res == "" {
    77  			res = f.CallerInfo[0]
    78  		} else {
    79  			res = res + separator + f.CallerInfo[0]
    80  		}
    81  	}
    82  	return res
    83  }