Find accepts a function that returns a boolean, runs it over the object elements, and returns the first element on which it returned true. If there are any failed assertions in the predicate function, the element is skipped without causing test failure. If no elements were found, a failure is repo
(fn func(key string, value *Value) bool)
| 555 | // }) |
| 556 | // foundValue.IsEqual(101) // succeeds |
| 557 | func (o *Object) Find(fn func(key string, value *Value) bool) *Value { |
| 558 | opChain := o.chain.enter("Find()") |
| 559 | defer opChain.leave() |
| 560 | |
| 561 | if opChain.failed() { |
| 562 | return newValue(opChain, nil) |
| 563 | } |
| 564 | |
| 565 | if fn == nil { |
| 566 | opChain.fail(AssertionFailure{ |
| 567 | Type: AssertUsage, |
| 568 | Errors: []error{ |
| 569 | errors.New("unexpected nil function argument"), |
| 570 | }, |
| 571 | }) |
| 572 | return newValue(opChain, nil) |
| 573 | } |
| 574 | |
| 575 | for _, kv := range o.sortedKV() { |
| 576 | found := false |
| 577 | |
| 578 | func() { |
| 579 | valueChain := opChain.replace("Find[%q]", kv.key) |
| 580 | defer valueChain.leave() |
| 581 | |
| 582 | valueChain.setRoot() |
| 583 | valueChain.setSeverity(SeverityLog) |
| 584 | |
| 585 | if fn(kv.key, newValue(valueChain, kv.val)) && !valueChain.treeFailed() { |
| 586 | found = true |
| 587 | } |
| 588 | }() |
| 589 | |
| 590 | if found { |
| 591 | return newValue(opChain, kv.val) |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | opChain.fail(AssertionFailure{ |
| 596 | Type: AssertValid, |
| 597 | Actual: &AssertionValue{o.value}, |
| 598 | Errors: []error{ |
| 599 | errors.New("expected: at least one object element matches predicate"), |
| 600 | }, |
| 601 | }) |
| 602 | |
| 603 | return newValue(opChain, nil) |
| 604 | } |
| 605 | |
| 606 | // FindAll accepts a function that returns a boolean, runs it over the object |
| 607 | // elements, and returns all the elements on which it returned true. |