func()

in internal/testutil/statespace/statespace.go [55:98]


func (m *Model[T, TT]) evaluate(fail func(msg string, args ...any)) {
	var testCases [][]bool
	for i := range 1 << len(m.transitions) {
		stack := make([]bool, len(m.transitions))
		for j := range m.transitions {
			stack[j] = (i>>j)&1 == 1
		}
		testCases = append(testCases, stack)
	}
	rand.Shuffle(len(testCases), func(i, j int) { testCases[i], testCases[j] = testCases[j], testCases[i] })

	for _, bitmap := range testCases {
		var state T
		if m.initial != nil {
			state = m.initial()
		}

		// Build the state by applying mutations
		for _, i := range rand.Perm(len(bitmap)) {
			if bitmap[i] {
				state = m.transitions[i].Func(state)
			}
		}

		var stack []string
		rand.Shuffle(len(m.invariants), func(i, j int) { m.invariants[i], m.invariants[j] = m.invariants[j], m.invariants[i] })
		for _, inv := range m.invariants {
			if inv.Assert(state, m.subject(state)) {
				continue
			}

			// Defer building the stack strings to avoid allocating the memory for passing tests
			if stack == nil {
				for i, enabled := range bitmap {
					if enabled {
						stack = append(stack, m.transitions[i].Name)
					}
				}
			}

			fail("invariant '%s' failed with mutation stack: [%s]", inv.Name, strings.Join(stack, ", "))
		}
	}
}