<commit_before>package require XOTcl
namespace import xotcl::*

namespace eval Spec {
    Class Expectations
    Expectations proc fail_with { message } {
        return -code error -errorcode "EXPECTATION_NOT_MET" $message
    }

    Class PositiveExpectationHandler
    PositiveExpectationHandler proc handle_matcher { actual matcher } {
        if { [$matcher matches? $actual] } { return }
        Expectations fail_with [$matcher failure_message]
    }

    Class NegativeExpectationHandler
    NegativeExpectationHandler proc handle_matcher { actual matcher } {
        if { [$matcher does_not_match? $actual] } { return }
        Expectations fail_with [$matcher negative_failure_message]
    }
}<commit_msg>Better backtraces for expectation failures.<commit_after>package require XOTcl
namespace import xotcl::*

namespace eval Spec {
    Class Expectations
    Expectations proc fail_with { message } {
        # Setting the return level here allows us to tweak generated backtraces
        # for expectation failures a bit. Thanks to this, the backtrace will
        # state that an error occurred during execution of "expect ...",
        # instead of during "Expectations fail_with ...".
        #
        # Also, this keeps the backtrace shorter and more focused, as we're
        # usually not concerned with what happens between the call to "expect"
        # and the generation of the expectation failure.
        #
        # TODO: The return level here is currently hard-coded, but it should be
        #       possible to determine the correct level programmatically.
        return -level 4 -code error -errorcode "EXPECTATION_NOT_MET" $message
    }

    Class PositiveExpectationHandler
    PositiveExpectationHandler proc handle_matcher { actual matcher } {
        if { [$matcher matches? $actual] } { return }
        Expectations fail_with [$matcher failure_message]
    }

    Class NegativeExpectationHandler
    NegativeExpectationHandler proc handle_matcher { actual matcher } {
        if { [$matcher does_not_match? $actual] } { return }
        Expectations fail_with [$matcher negative_failure_message]
    }
}
{'fraction_non_alphanumeric': 0.06299580027998133, 'fraction_numerical': 0.0004666355576294914, 'mean_word_length': 3.1151631477927064, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6793172', 'n_tokens_mistral': 560, 'n_tokens_neox': 531, 'n_words': 196}