Documentation
¶
Overview ¶
Package minitest is a pure-Go (CGO-free) re-implementation of the CORE of Ruby's Minitest test framework (targeting Minitest 5.x): the assertion layer, the per-test run lifecycle, result aggregation, the spec DSL → assertion mapping, and the Mock / Stub object framework.
It is the deterministic, interpreter-independent heart of Minitest — the part that, given a Ruby runtime to supply value semantics, produces the exact same assertion failure messages, mu_pp inspection output, and run-result counts as the minitest gem, byte-for-byte. A host such as go-embedded-ruby (rbgo) binds it so that real Minitest test suites run on a pure-Go Ruby.
What this package owns ¶
- Assertions: every assert_*/refute_* method, flunk, skip, pass — and, the load-bearing part, the EXACT failure message each produces (the "Expected: 1\n Actual: 2" of assert_equal, the mu_pp inspection, the custom-message prepend via [Assertions.Message]).
- The run lifecycle: [Test.Run] drives before_setup/setup/after_setup → the test body → before_teardown/teardown/after_teardown, captures exceptions into failures, and produces a Result.
- Result: assertion count, failures / errors / skips, result_code, result_label, location, and the to_s rendering.
- The exception model: Assertion, Skip, UnexpectedError.
- The spec DSL surface: describe/it/before/after and the must_*/wont_* expectation → assertion mapping (Expectations).
- Mock (expect / verify) and Stub (stub a method for a block), including the exact MockExpectationError / ArgumentError messages.
What is a seam (supplied by the host) ¶
Everything that requires genuine Ruby object semantics is funneled through the Runtime interface, which the host (rbgo) implements over its own object graph:
- value inspection (#inspect), equality (#==), identity (#equal? / object_id), regexp match (#=~), #respond_to?, #include?, #empty?, #nil?, #instance_of?, #kind_of?, class name, truthiness, and arbitrary #__send__ for operator / predicate assertions.
The IO captured by assert_output / assert_silent and the execution of test method BODIES and assertion blocks are also seams — the host wires those to the Ruby VM. This package never evaluates Ruby; it only formats, orchestrates, and aggregates.
Index ¶
- Constants
- Variables
- func ItName(seq int, desc string) string
- func RunTest(body TestBody, elapsed float64) (res *Result, abort *Passthrough)
- func SpecType(matches []bool) int
- func Stub(h StubHarness) (err error)
- func ValidateLetName(name string, reservedMethods []string) string
- type Assertion
- type Assertions
- func (a *Assertions) Assert(test Value, msg string) error
- func (a *Assertions) AssertEmpty(obj Value, msg string) error
- func (a *Assertions) AssertEqual(exp, act Value, msg string) (err error, deprecated bool)
- func (a *Assertions) AssertInDelta(exp, act, delta float64, msg string) error
- func (a *Assertions) AssertInEpsilon(exp, act, epsilon float64, msg string) error
- func (a *Assertions) AssertIncludes(collection, obj Value, msg string) error
- func (a *Assertions) AssertInstanceOf(cls, obj Value, msg string) error
- func (a *Assertions) AssertKindOf(cls, obj Value, msg string) error
- func (a *Assertions) AssertMatch(matcher, obj Value, msg string) error
- func (a *Assertions) AssertNil(obj Value, msg string) error
- func (a *Assertions) AssertOperator(o1 Value, op string, o2 Value, msg string) error
- func (a *Assertions) AssertOutput(stderrResult, stdoutResult error) error
- func (a *Assertions) AssertPredicate(o1 Value, op, msg string) error
- func (a *Assertions) AssertRaises(out RaiseOutcome, customMsg, expArrayInspect, expSingleInspect string) (reRaise bool, err error)
- func (a *Assertions) AssertRespondTo(obj Value, meth, msg string, includeAll bool) error
- func (a *Assertions) AssertSame(exp, act Value, msg string) error
- func (a *Assertions) AssertThrows(out ThrowOutcome, symInspect string, msg string) error
- func (a *Assertions) Flunk(msg string) error
- func (a *Assertions) MuPP(obj Value) string
- func (a *Assertions) MuPPForDiff(obj Value) string
- func (a *Assertions) OutputRequiresBlock() error
- func (a *Assertions) Pass() error
- func (a *Assertions) RaisesRequiresBlock() error
- func (a *Assertions) Refute(test Value, msg string) error
- func (a *Assertions) RefuteEmpty(obj Value, msg string) error
- func (a *Assertions) RefuteEqual(exp, act Value, msg string) error
- func (a *Assertions) RefuteInDelta(exp, act, delta float64, msg string) error
- func (a *Assertions) RefuteInEpsilon(exp, act, epsilon float64, msg string) error
- func (a *Assertions) RefuteIncludes(collection, obj Value, msg string) error
- func (a *Assertions) RefuteInstanceOf(cls, obj Value, msg string) error
- func (a *Assertions) RefuteKindOf(cls, obj Value, msg string) error
- func (a *Assertions) RefuteMatch(matcher, obj Value, msg string) error
- func (a *Assertions) RefuteNil(obj Value, msg string) error
- func (a *Assertions) RefuteOperator(o1 Value, op string, o2 Value, msg string) error
- func (a *Assertions) RefutePredicate(o1 Value, op, msg string) error
- func (a *Assertions) RefuteRespondTo(obj Value, meth, msg string, includeAll bool) error
- func (a *Assertions) RefuteSame(exp, act Value, msg string) error
- func (a *Assertions) SkipError(msg string) *Skip
- type Expectation
- type Flip
- type KV
- type Mock
- type MockArgumentError
- type MockExpectationError
- type MockMatcher
- type MockNoMethodError
- type Passthrough
- type RaiseOutcome
- type Reportable2
- type Result
- type Runtime
- type Skip
- type StubHarness
- type TestBody
- type ThrowOutcome
- type UnexpectedError
- type Value
Constants ¶
const DefaultItDesc = "anonymous"
DefaultItDesc is the description it uses when none is given ("anonymous"); the host also substitutes the skip("(no tests defined)") body when no block is passed.
const E = "\x00E\x00"
E is the empty-ending sentinel assert_equal passes so its diff message gets no trailing ".", matching `message(msg, E) { diff exp, act }`.
const VERSION = "5.25.5"
VERSION is the Minitest version this package targets and reports. The failure messages, mu_pp output, and run-result semantics reproduced here are the 5.x ones (assert_equal nil deprecation-warns rather than failing, etc.).
Variables ¶
var SetupMethods = []string{"before_setup", "setup", "after_setup"}
SetupMethods is Minitest::Test::SETUP_METHODS — the hooks run, in order, before the test body, all inside one capture_exceptions.
var TeardownMethods = []string{"before_teardown", "teardown", "after_teardown"}
TeardownMethods is Minitest::Test::TEARDOWN_METHODS — the hooks run, in order, after the test body, EACH inside its own capture_exceptions.
var UNDEFINED = &undefined{}
UNDEFINED is Minitest::Assertions::UNDEFINED, the sentinel distinguishing assert_operator's 2-arg (predicate) and 3-arg (operator) forms. Its inspect is "UNDEFINED".
Functions ¶
func ItName ¶
ItName reproduces Minitest::Spec::DSL#it's method-name morphing:
name = "test_%04d_%s" % [@specs, desc]
where seq is the 1-based count of it/specify blocks defined so far in the describe class. The host maintains the counter and the define_method; this function owns the exact name format the reporter and filters key off of.
func RunTest ¶
func RunTest(body TestBody, elapsed float64) (res *Result, abort *Passthrough)
RunTest reproduces Minitest::Test#run: it runs the setup hooks and the body in one capture, then each teardown hook in its own capture, accumulating failures, and returns the *Result (Result.from self). If a passthrough exception occurs, abort is the wrapping *Passthrough and the partial result is still returned (Ruby would unwind, but the host decides what to do with abort).
elapsed is the measured wall time for the whole run (time_it); the host clocks it around the call, or passes a deterministic value in tests.
func SpecType ¶
SpecType reproduces Minitest::Spec::DSL#spec_type's selection: it walks the registered (matcher, class) pairs newest-first and returns the index of the first whose matcher matches desc. A matcher is either a callable (the host evaluates it and reports the boolean via callMatch) or a Regexp/=== matcher (the host reports the boolean via the same callback). The base registration (//, Minitest::Spec) always matches, so a valid index is always returned.
matches[i] is the precomputed boolean of registration i against desc, in the SAME order DSL::TYPES holds them (newest unshifted to the front). SpecType returns the first true index.
func Stub ¶
func Stub(h StubHarness) (err error)
Stub reproduces Object#stub's control flow: Install the stub, run the block, and ALWAYS Restore afterward (the Ruby `ensure`), even if Install's precondition fails or the block raises. The block's error (or Install's) is returned; Restore's effect is unconditional.
func ValidateLetName ¶
ValidateLetName reproduces Minitest::Spec::DSL#let's name guard. It returns a non-empty error message (the exact ArgumentError text) when name is illegal: it may not begin with "test", and may not override a Minitest::Spec instance method (other than "subject"). reservedMethods is the host-supplied list of Minitest::Spec instance-method names (already excluding "subject"), so the override check stays interpreter-faithful without this package hardcoding the method set.
Types ¶
type Assertion ¶
type Assertion struct {
Msg string
// Backtrace is the (already filtered or raw) Ruby backtrace, most-recent
// frame first, as the host captured it. Location uses it to point at the
// offending line.
Backtrace []string
}
Assertion is Minitest::Assertion — the failure raised by a failing assertion. In Ruby it subclasses Exception (not StandardError) so test bodies don't accidentally rescue it. Here it is a Go error carrying the failure message and the backtrace the host supplies for the raising frame.
func (*Assertion) Location ¶
Location returns the "file:line" the assertion should be attributed to: the frame just past the deepest assertion-helper frame (Minitest::Assertion#location). bt is the already-backtrace-filtered list (host responsibility), most-recent frame first as Ruby presents it. The ":in ..." suffix is stripped.
func (*Assertion) ResultCode ¶
ResultCode is the single-character code for a plain Assertion ("F").
func (*Assertion) ResultLabel ¶
ResultLabel is the long label for this kind of result: "Failure".
type Assertions ¶
type Assertions struct {
// Count mirrors the Ruby `assertions` accessor: every assert call bumps it.
Count int
// contains filtered or unexported fields
}
Assertions is Minitest::Assertions bound to a Runtime. It owns the assertion counter and produces the exact failure messages of the minitest gem. Each assert_*/refute_* method returns nil on success or a non-nil error (an *Assertion or *Skip) describing the failure; the host raises it in the Ruby VM and the lifecycle ([Test]) captures it.
The value-level comparisons (==, =~, inspect, include?, …) are delegated to the Runtime; this type owns only the formatting and the assertion bookkeeping.
func NewAssertions ¶
func NewAssertions(rt Runtime) *Assertions
NewAssertions returns an Assertions backed by rt.
func (*Assertions) Assert ¶
func (a *Assertions) Assert(test Value, msg string) error
Assert is Minitest::Assertions#assert: increments the count and fails with msg (default "Expected #{mu_pp test} to be truthy.") unless test is truthy.
func (*Assertions) AssertEmpty ¶
func (a *Assertions) AssertEmpty(obj Value, msg string) error
AssertEmpty is assert_empty. It first asserts obj responds to :empty? (so a non-respond_to value fails with the respond_to message), then asserts empty.
func (*Assertions) AssertEqual ¶
func (a *Assertions) AssertEqual(exp, act Value, msg string) (err error, deprecated bool)
AssertEqual is assert_equal. On failure the message is the diff form ("Expected: …\n Actual: …"). It returns, additionally, the 5.x nil-deprecation signal: when exp is nil and the host wants the warning, deprecated is true (the gem warns rather than failing in 5.x). The host emits the warning text; the assertion result itself is unaffected.
func (*Assertions) AssertInDelta ¶
func (a *Assertions) AssertInDelta(exp, act, delta float64, msg string) error
AssertInDelta is assert_in_delta. n = |exp - act|; fails unless delta >= n. The message interpolates exp/act/n/delta via Ruby #to_s, which the host renders by formatting the float values; here exp/act/delta/n are Go float64.
func (*Assertions) AssertInEpsilon ¶
func (a *Assertions) AssertInEpsilon(exp, act, epsilon float64, msg string) error
AssertInEpsilon is assert_in_epsilon: delegates to assert_in_delta with delta = min(|exp|, |act|) * epsilon.
func (*Assertions) AssertIncludes ¶
func (a *Assertions) AssertIncludes(collection, obj Value, msg string) error
AssertIncludes is assert_includes.
func (*Assertions) AssertInstanceOf ¶
func (a *Assertions) AssertInstanceOf(cls, obj Value, msg string) error
AssertInstanceOf is assert_instance_of.
func (*Assertions) AssertKindOf ¶
func (a *Assertions) AssertKindOf(cls, obj Value, msg string) error
AssertKindOf is assert_kind_of.
func (*Assertions) AssertMatch ¶
func (a *Assertions) AssertMatch(matcher, obj Value, msg string) error
AssertMatch is assert_match. A String matcher is promoted to a Regexp first (so the message shows the original matcher's inspect). It asserts matcher responds to :=~, then asserts the match.
func (*Assertions) AssertNil ¶
func (a *Assertions) AssertNil(obj Value, msg string) error
AssertNil is assert_nil.
func (*Assertions) AssertOperator ¶
AssertOperator is assert_operator: fails unless o1.__send__(op, o2). When o2 is the UNDEFINED sentinel it delegates to assert_predicate.
func (*Assertions) AssertOutput ¶
func (a *Assertions) AssertOutput(stderrResult, stdoutResult error) error
AssertOutput is assert_output. The host captures stdout/stderr from the block and reports them. stdoutExp/stderrExp are the expectations: nil means "don't care"; a string means exact match; a regexp means pattern. The host signals which mode applies per stream and supplies, for an exact-string mismatch, the diff message, or for a regexp mismatch, the assert_match message.
To keep the assertion logic pure, the comparison itself is done by the host (it owns == and =~ over Ruby strings/regexps); AssertOutput is handed the already-decided pass/fail and, on failure, the composed sub-message. It returns nil on full success or the first failing stream's *Assertion.
outErr/outStd are per-stream results: nil = stream not checked or passed.
func (*Assertions) AssertPredicate ¶
func (a *Assertions) AssertPredicate(o1 Value, op, msg string) error
AssertPredicate is assert_predicate: fails unless o1.__send__(op).
func (*Assertions) AssertRaises ¶
func (a *Assertions) AssertRaises(out RaiseOutcome, customMsg, expArrayInspect, expSingleInspect string) (reRaise bool, err error)
AssertRaises is assert_raises. exp are the expected exception-class Values (their inspect is used in messages); customMsg is an optional leading message the gem renders as "#{msg}.\n" when present (it was the trailing String arg).
It returns (reRaise, err): when reRaise is non-nil the host must re-raise that exact outcome's exception (the Assertion/Skip/Signal/SystemExit passthrough cases). Otherwise err is nil on success (the matched exception is "returned" by the host from its own block driver) or an *Assertion describing the failure.
expInspect is mu_pp(exp) when exp has >1 element, else mu_pp(exp.first) — the host passes the already-inspected forms via expSingleInspect (for the size==1 "expected but nothing raised" / unexpected-error case) and expArrayInspect.
func (*Assertions) AssertRespondTo ¶
func (a *Assertions) AssertRespondTo(obj Value, meth, msg string, includeAll bool) error
AssertRespondTo is assert_respond_to.
func (*Assertions) AssertSame ¶
func (a *Assertions) AssertSame(exp, act Value, msg string) error
AssertSame is assert_same: fails unless exp.equal?(act).
func (*Assertions) AssertThrows ¶
func (a *Assertions) AssertThrows(out ThrowOutcome, symInspect string, msg string) error
AssertThrows is assert_throws. symInspect is mu_pp(sym) (e.g. ":foo"). When the host caught a *different* symbol it sets OtherSym so the message gains the ", not …" tail, matching the gem's ArgumentError/NameError handling.
func (*Assertions) Flunk ¶
func (a *Assertions) Flunk(msg string) error
Flunk is Minitest::Assertions#flunk: always fails with msg (default "Epic Fail!").
func (*Assertions) MuPP ¶
func (a *Assertions) MuPP(obj Value) string
MuPP is Minitest::Assertions#mu_pp: a human-readable rendering of obj. It is obj.inspect, re-encoded to the default external encoding; for a String whose encoding differs from the default external (or is invalid) it is prefixed with "# encoding:" / "# valid:" annotation lines, exactly as the gem does.
The encoding re-encode itself is a no-op at the string level here (the host's Inspect already yields the bytes); the annotation branch is what the gem's callers observe, and it is reproduced faithfully.
func (*Assertions) MuPPForDiff ¶
func (a *Assertions) MuPPForDiff(obj Value) string
MuPPForDiff is Minitest::Assertions#mu_pp_for_diff: a more diff-able rendering. It runs Assertions.MuPP first, then, when the inspected string contains EITHER single-escaped newlines ("\n") OR double-escaped ("\\n") but not both, unescapes them, and finally anonymizes hex object ids. This is used when building a structural diff; the package exposes it because hosts and tests assert on it.
func (*Assertions) OutputRequiresBlock ¶
func (a *Assertions) OutputRequiresBlock() error
OutputRequiresBlock returns the flunk the gem raises when assert_output is called without a block.
func (*Assertions) Pass ¶
func (a *Assertions) Pass() error
Pass is Minitest::Assertions#pass: counts an assertion and always succeeds.
func (*Assertions) RaisesRequiresBlock ¶
func (a *Assertions) RaisesRequiresBlock() error
RaisesRequiresBlock returns the flunk assert_raises raises without a block.
func (*Assertions) Refute ¶
func (a *Assertions) Refute(test Value, msg string) error
Refute is Minitest::Assertions#refute: fails if test is truthy.
func (*Assertions) RefuteEmpty ¶
func (a *Assertions) RefuteEmpty(obj Value, msg string) error
RefuteEmpty is refute_empty.
func (*Assertions) RefuteEqual ¶
func (a *Assertions) RefuteEqual(exp, act Value, msg string) error
RefuteEqual is refute_equal.
func (*Assertions) RefuteInDelta ¶
func (a *Assertions) RefuteInDelta(exp, act, delta float64, msg string) error
RefuteInDelta is refute_in_delta.
func (*Assertions) RefuteInEpsilon ¶
func (a *Assertions) RefuteInEpsilon(exp, act, epsilon float64, msg string) error
RefuteInEpsilon is refute_in_epsilon: delegates to refute_in_delta with delta = exp * epsilon (note: the gem uses a*epsilon, not min, for refute).
func (*Assertions) RefuteIncludes ¶
func (a *Assertions) RefuteIncludes(collection, obj Value, msg string) error
RefuteIncludes is refute_includes.
func (*Assertions) RefuteInstanceOf ¶
func (a *Assertions) RefuteInstanceOf(cls, obj Value, msg string) error
RefuteInstanceOf is refute_instance_of.
func (*Assertions) RefuteKindOf ¶
func (a *Assertions) RefuteKindOf(cls, obj Value, msg string) error
RefuteKindOf is refute_kind_of.
func (*Assertions) RefuteMatch ¶
func (a *Assertions) RefuteMatch(matcher, obj Value, msg string) error
RefuteMatch is refute_match.
func (*Assertions) RefuteNil ¶
func (a *Assertions) RefuteNil(obj Value, msg string) error
RefuteNil is refute_nil.
func (*Assertions) RefuteOperator ¶
RefuteOperator is refute_operator.
func (*Assertions) RefutePredicate ¶
func (a *Assertions) RefutePredicate(o1 Value, op, msg string) error
RefutePredicate is refute_predicate.
func (*Assertions) RefuteRespondTo ¶
func (a *Assertions) RefuteRespondTo(obj Value, meth, msg string, includeAll bool) error
RefuteRespondTo is refute_respond_to.
func (*Assertions) RefuteSame ¶
func (a *Assertions) RefuteSame(exp, act Value, msg string) error
RefuteSame is refute_same.
type Expectation ¶
type Expectation struct {
// Method is the must_/wont_ name (e.g. "must_equal").
Method string
// Assertion is the underlying assert_/refute_ name (e.g. "assert_equal").
Assertion string
// Flip is how target/args bind to the assertion's parameters.
Flip Flip
}
Expectation maps a must_*/wont_* expectation to its underlying assertion. Mapped is built from minitest/expectations.rb's infect_an_assertion table.
func Expectations ¶
func Expectations() []Expectation
Expectations lists every supported must_*/wont_* expectation in declaration order. Hosts iterate it to install the DSL methods.
func LookupExpectation ¶
func LookupExpectation(method string) (Expectation, bool)
LookupExpectation returns the Expectation mapping for a must_/wont_ method name and whether it is known.
func (Expectation) BindArgs ¶
func (e Expectation) BindArgs(target Value, args []Value) (out []Value, blockIsTarget bool)
BindArgs computes the positional arguments to pass to the underlying assertion for an expectation call, given the expectation target and the expectation's own args, per the Flip rule. For FlipBlock the target is the block (not a positional arg), so the returned args are the expectation args unchanged and blockIsTarget is true; the host passes target as the &block. For the other flips the returned slice is the full positional argument list.
type Flip ¶
type Flip int
Flip describes how an expectation's receiver and arguments map onto the underlying assertion's positional parameters (the third arg to infect_an_assertion). The zero value FlipDefault is the common case.
const ( // FlipDefault: ctx.meth(args.first, target, *args[1..-1]) — the expectation // target becomes the assertion's SECOND positional arg (the "actual"), and // the first expectation arg becomes the first (the "expected"). Used by // must_equal, must_be_instance_of, etc. FlipDefault Flip = iota // FlipReverse (:reverse / dont_flip): ctx.meth(target, *args) — target stays // first. Used by must_include, must_be, must_respond_to, etc. FlipReverse // FlipUnary (:unary): like reverse, target first, no extra args. Used by // must_be_nil, must_be_empty, etc. (modeled identically to reverse here, as // the gem's :unary is also dont_flip=true). FlipUnary // FlipBlock (:block): ctx.meth(*args, &target) when target is a Proc — the // expectation target is the BLOCK. Used by must_raise, must_output, etc. FlipBlock )
type Mock ¶
type Mock struct {
// contains filtered or unexported fields
}
Mock is Minitest::Mock: a clean mock object. expect queues expectations; the host routes method calls into Mock.Call; verify checks all queued expectations were met. Argument case-equality and block invocation are delegated to a MockMatcher.
func (*Mock) Call ¶
Call routes a method invocation into the mock, reproducing Mock#method_missing. It returns the expectation's retval on success, or an error: *MockNoMethodError for an unmocked name, *MockExpectationError for no-more-expects / wrong args / failed block / wrong keywords, or *MockArgumentError for an arity mismatch.
func (*Mock) Expect ¶
Expect queues an expectation for name with return value retval and expected positional args / keyword matchers. It mirrors Mock#expect's argument validation, returning the ArgumentError the gem raises when args is misused. Pass block=true (with empty args/kwargs) for the block-validated form.
func (*Mock) ExpectAnyKwargs ¶
ExpectAnyKwargs queues an expectation whose keyword matching accepts any keywords (the gem's `Hash == expected_kwargs` branch, set when expect is given the Hash class itself as the kwargs matcher).
func (*Mock) Verify ¶
Verify reproduces Mock#verify. For each queued method: if it was never called at all (actual defaults to nil), it raises "Expected <expected[0]>"; if it was called but fewer times than expected, it raises "Expected <expected[actual.size]>, got [<actual calls>]". Else returns nil.
type MockArgumentError ¶
type MockArgumentError struct{ Msg string }
MockArgumentError is the Ruby ArgumentError Mock raises on an arity mismatch. It is distinct from MockExpectationError because the gem raises ArgumentError (not MockExpectationError) for wrong argument/keyword counts.
func (*MockArgumentError) Error ¶
func (e *MockArgumentError) Error() string
Error implements error.
type MockExpectationError ¶
type MockExpectationError struct{ Msg string }
MockExpectationError is Minitest's MockExpectationError, raised by Mock when it is not called as expected (verify, no-more-expects, argument mismatch).
func (*MockExpectationError) Error ¶
func (e *MockExpectationError) Error() string
Error implements error.
type MockMatcher ¶
type MockMatcher interface {
// Match reports whether expected matches actual under Ruby case-equality.
Match(expected, actual Value) bool
// Inspect renders v as Ruby #inspect would (for error messages).
Inspect(v Value) string
// CallBlock invokes the block given to expect with the actual args/kwargs and
// reports its truthiness (the gem's val_block.call(*args, **kwargs, &block)).
CallBlock(idx int, args []Value, kwargs []KV) bool
}
MockMatcher is the seam for Ruby case-equality used during mock argument matching: Match reports (expected === actual) || (expected == actual), and Inspect renders a Value for the error messages (Ruby #inspect). It is a narrow slice of Runtime; a host can reuse the same implementation.
type MockNoMethodError ¶
type MockNoMethodError struct{ Msg string }
MockNoMethodError is the Ruby NoMethodError Mock raises for an unmocked, undelegated method.
func (*MockNoMethodError) Error ¶
func (e *MockNoMethodError) Error() string
Error implements error.
type Passthrough ¶
type Passthrough struct{ Err error }
Passthrough wraps an exception that must abort the run rather than be recorded as a failure (NoMemoryError, SignalException, SystemExit). The host returns it from TestBody.Invoke; RunTest propagates it via the returned abort value.
type RaiseOutcome ¶
type RaiseOutcome struct {
Raised bool
ErrClass string
ErrMessage string
Backtrace []string // already minitest-filtered by the host
Matched bool // raised class is a member of exp
IsAssertion bool // raised was Minitest::Assertion (incl Skip/UnexpectedError)
IsPassthrough bool // raised was SignalException or SystemExit
}
RaiseOutcome is what the host reports after running an assert_raises block: the block either raised an exception (Raised true) or returned normally. When it raised, ErrClass/ErrMessage/Backtrace describe it. The host classifies whether the raised class is one of the expected classes (Matched) and whether it was itself a Minitest Assertion/Skip (IsAssertion) or a SignalException/SystemExit (IsPassthrough), since those re-raise rather than fail.
type Reportable2 ¶
Reportable2 is the minimal interface a failure exposes for result coding: a long label whose first letter is the single-character code. (Assertion, Skip, UnexpectedError all satisfy it.)
type Result ¶
type Result struct {
Klass string
TestName string
Assertions int
// Failures holds Assertion/Skip/UnexpectedError values captured during the
// run, in the order capture_exceptions appended them.
Failures []Reportable2
Time float64
// SourceFile/SourceLine mirror Result#source_location.
SourceFile string
SourceLine int
}
Result is Minitest::Result — a marshalable snapshot of one test run. It holds the class/name, assertion count, the captured failures (in occurrence order), and timing. Its rendering and predicates match the gem.
func (*Result) Errored ¶
Errored reports whether any failure is an UnexpectedError (Reportable#error?).
func (*Result) Failure ¶
func (r *Result) Failure() Reportable2
Failure returns the first captured failure, or nil (Reportable#failure).
func (*Result) Location ¶
Location returns the test's location string (Reportable#location): "Class#name" plus " [file:line]" of the failure unless the run passed or errored. baseDir, when non-empty and a prefix of the failure location, is stripped (Ruby's delete_prefix BASE_DIR); the host passes Dir.pwd+"/".
func (*Result) Passed ¶
Passed reports whether the run passed: no failure (Reportable#passed?). Skips are NOT passing.
func (*Result) ResultCode ¶
ResultCode returns ".", "F", "E", or "S" (Reportable#result_code): the failure's code, or "." when passed.
type Runtime ¶
type Runtime interface {
// Inspect returns obj.inspect — the Ruby #inspect string. This is the raw
// material of mu_pp; the package layers encoding annotations and diff cleanup
// on top of it (see [Assertions.MuPP]).
Inspect(obj Value) string
// Encoding returns the name of obj's string encoding (e.g. "UTF-8") and
// whether the string is validly encoded. It is consulted by mu_pp only for
// String values whose encoding differs from the default external encoding or
// which are invalid. For non-strings the result is ignored.
Encoding(obj Value) (name string, valid bool)
// DefaultExternalEncoding returns Encoding.default_external's name. mu_pp
// annotates a String whose encoding differs from this.
DefaultExternalEncoding() string
// IsString reports whether obj is a Ruby String (String === obj). Used by
// mu_pp (encoding annotation) and by assert_match (string→regexp promotion).
IsString(obj Value) bool
// Equal reports obj == other (Ruby #==). Drives assert_equal / refute_equal.
Equal(a, b Value) bool
// Same reports a.equal?(b) — Ruby object identity. Drives assert_same /
// refute_same.
Same(a, b Value) bool
// ObjectID returns obj.object_id, used verbatim in the assert_same /
// refute_same failure message.
ObjectID(obj Value) int64
// Truthy reports Ruby truthiness: false only for nil and false.
Truthy(obj Value) bool
// IsNil reports obj.nil?.
IsNil(obj Value) bool
// Match returns the truthiness of (matcher =~ obj). The host evaluates the
// Ruby =~ operator (Regexp#=~, String#=~, or a custom one). assert_match has
// already promoted a bare String matcher to a Regexp before calling, by way
// of [Runtime.StringToRegexp].
Match(matcher, obj Value) bool
// StringToRegexp builds Regexp.new(Regexp.escape(s)) for a String matcher, so
// assert_match / refute_match match the gem's literal-string promotion.
StringToRegexp(s Value) Value
// RespondTo reports obj.respond_to?(meth, includeAll).
RespondTo(obj Value, meth string, includeAll bool) bool
// Includes reports collection.include?(obj).
Includes(collection, obj Value) bool
// Empty reports obj.empty?.
Empty(obj Value) bool
// InstanceOf reports obj.instance_of?(cls).
InstanceOf(obj, cls Value) bool
// KindOf reports obj.kind_of?(cls).
KindOf(obj, cls Value) bool
// ClassName returns obj.class.name — used in several messages (e.g.
// assert_instance_of's "not #{obj.class}", assert_respond_to's "(#{obj.class})").
ClassName(obj Value) string
// Name returns the printable name of a class/module Value (its #to_s / #name),
// used where the gem interpolates a bare class such as assert_instance_of's
// "to be an instance of #{cls}".
Name(cls Value) string
// Send invokes obj.__send__(op, args...) and returns the result, used by
// assert_operator / assert_predicate (and their refute_ twins). op is the
// Ruby method name (e.g. "<=", "empty?").
Send(obj Value, op string, args ...Value) Value
}
Runtime is the seam through which this package obtains genuine Ruby value semantics. The host (rbgo) implements it over its object graph. Every method corresponds to a Ruby message the assertion layer would otherwise have sent to a Ruby object; keeping them here makes the assertion logic pure and the value semantics the host's responsibility.
All methods must be deterministic for a given pair of arguments so the failure messages this package builds are reproducible.
type Skip ¶
type Skip struct {
Assertion
}
Skip is Minitest::Skip — the assertion raised by skip. It is an Assertion subclass whose result label is "Skipped".
type StubHarness ¶
type StubHarness interface {
// Install replaces the method named by the stub: it aliases the original
// under "__minitest_stub__<name>" and defines a replacement that, when the
// stub value responds to :call, calls it, else returns the value as-is
// (yielding block_args to a passed block when given). Returns an error if the
// method does not already exist (the gem requires it).
Install() error
// RunBlock runs the user block with the (possibly stubbed) receiver as its
// argument (block[self]) and returns its error/exception, if any.
RunBlock() error
// Restore undoes Install: undef the replacement, alias the original back, and
// undef the temp alias. It must run even when RunBlock errors (the ensure).
Restore()
}
StubHarness is the seam the host implements to stub a single method on an object for the duration of a block (Object#stub). The library owns only the install → run → restore orchestration (the Ruby method's `ensure`); the host performs the actual singleton-method alias/define/undef and runs the user block.
type TestBody ¶
type TestBody interface {
// Invoke calls the named instance method (e.g. "setup", "test_foo"). It
// returns the captured exception, already classified, or nil on success.
Invoke(method string) error
// Name is the name of the test method this instance runs (the Ruby `name`).
Name() string
// ClassName is the test's class name, for Result/location.
ClassName() string
// Assertions returns the current assertion count to record into the Result.
Assertions() int
// SourceLocation returns the ["file", line] of the test method (Result.from).
SourceLocation() (string, int)
}
TestBody is the seam the host implements to run one test method instance: it invokes a named method (a setup/teardown hook or the test body) in the Ruby VM. Invoke returns nil if the method completed normally, or an error describing the exception it raised. The error must be an *Assertion / *Skip when an assertion failed or a skip was requested, an *UnexpectedError for any other Ruby exception, or one of the passthrough sentinels (see Passthrough) for NoMemoryError / SignalException / SystemExit, which abort the run.
type ThrowOutcome ¶
type ThrowOutcome struct {
Caught bool
OtherSym string // the symbol actually thrown, when different from sym
}
ThrowOutcome is what the host reports after an assert_throws block: whether the expected symbol was thrown (Caught), and, for the "not :other" message tail, the name of a different symbol that was thrown instead (OtherSym, "" if none).
type UnexpectedError ¶
type UnexpectedError struct {
Assertion
// ErrorClass is the wrapped error's class name (e.g. "RuntimeError").
ErrorClass string
// ErrorMessage is the wrapped error's #message.
ErrorMessage string
}
UnexpectedError is Minitest::UnexpectedError — wraps an error that was raised during a run but was not an Assertion (a genuine test error). Its message and backtrace come from the wrapped error; the host supplies ErrorClass / ErrorMessage / the (filtered) backtrace.
func (*UnexpectedError) Message ¶
func (u *UnexpectedError) Message() string
Message renders the Minitest::UnexpectedError#message:
"#{error.class}: #{error.message}\n #{filtered_backtrace.join("\n ")}"
The host has already filtered the backtrace and stripped the Dir.pwd prefix from each frame (those are environment concerns); this method only joins.
func (*UnexpectedError) ResultCode ¶
func (u *UnexpectedError) ResultCode() string
ResultCode returns "E".
func (*UnexpectedError) ResultLabel ¶
func (u *UnexpectedError) ResultLabel() string
ResultLabel returns "Error".
type Value ¶
type Value = any
Value is an opaque Ruby value handed across the seam. This package never inspects its concrete shape; it only passes it back to the Runtime for the Ruby-semantic operations (inspect, ==, =~, …). A host represents it however it likes (its own object pointer, an interface, etc.).
