func Test_diffHalfmatchTest(t *testing.T) { dmp := New() dmp.DiffTimeout = 1 // No match. assert.True(t, dmp.DiffHalfMatch("1234567890", "abcdef") == nil, "") assert.True(t, dmp.DiffHalfMatch("12345", "23") == nil, "") // Single Match. assertStrEqual(t, []string{"12", "90", "a", "z", "345678"}, dmp.DiffHalfMatch("1234567890", "a345678z")) assertStrEqual(t, []string{"a", "z", "12", "90", "345678"}, dmp.DiffHalfMatch("a345678z", "1234567890")) assertStrEqual(t, []string{"abc", "z", "1234", "0", "56789"}, dmp.DiffHalfMatch("abc56789z", "1234567890")) assertStrEqual(t, []string{"a", "xyz", "1", "7890", "23456"}, dmp.DiffHalfMatch("a23456xyz", "1234567890")) // Multiple Matches. assertStrEqual(t, []string{"12123", "123121", "a", "z", "1234123451234"}, dmp.DiffHalfMatch("121231234123451234123121", "a1234123451234z")) assertStrEqual(t, []string{"", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="}, dmp.DiffHalfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=")) assertStrEqual(t, []string{"-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"}, dmp.DiffHalfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy")) // Non-optimal halfmatch. // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy assertStrEqual(t, []string{"qHillo", "w", "x", "Hulloy", "HelloHe"}, dmp.DiffHalfMatch("qHilloHelloHew", "xHelloHeHulloy")) // Optimal no halfmatch. dmp.DiffTimeout = 0 assert.True(t, dmp.DiffHalfMatch("qHilloHelloHew", "xHelloHeHulloy") == nil, "") }
func Test_ListNode_basics(t *testing.T) { node0 := NewStubNode("foo") node1 := NewStubNode("bar baz") node2 := NewStubNode("qux") list1 := newListNode(node0, node1, node2) assert.Equal(t, "ListNode", list1.Typename()) assert.Equal(t, "foo,bar baz,qux", list1.Name()) assert.Equal(t, `["foo", "bar baz", "qux"]`, list1.String()) assert.Equal(t, "foo,bar baz,qux", list1.ValueString()) assert.Equal(t, "foo 'bar baz' qux", list1.CommandString()) expect1 := []types.FuObject{node0, node1, node2} assert.Equal(t, expect1, list1.List()) expect2 := []Node{node0, node1, node2} assert.Equal(t, expect2, list1.Nodes()) list2 := newListNode(node0, node1, node2) assert.True(t, list1.Equal(list2)) list3 := newListNode(node1, node0, node2) assert.False(t, list1.Equal(list3)) list4 := list3.copy().(*ListNode) assert.False(t, list3 == list4) assert.True(t, list3.Equal(list4)) }
func TestPathMatchHandler(t *testing.T) { pathPattern, _ := paths.NewPathPattern("collection/{id}/name") var called bool = false h := NewPathMatchHandler(pathPattern, HandlerExecutionFunc(func(c context.Context) error { called = true return nil })) ctx1 := context_test.MakeTestContextWithPath("/collection/123/name") will, _ := h.WillHandle(ctx1) assert.True(t, will) h.Handle(ctx1) assert.True(t, called, "Method should be called") assert.Equal(t, "123", ctx1.Data().Get(context.DataKeyPathParameters).(objects.Map).Get("id")) ctx2 := context_test.MakeTestContextWithPath("/collection") will, _ = h.WillHandle(ctx2) assert.False(t, will) assert.Nil(t, ctx2.Data().Get(context.DataKeyPathParameters)) h.BreakCurrentPipeline = true shouldStop, handleErr := h.Handle(ctx2) assert.Nil(t, handleErr) assert.True(t, shouldStop) assert.True(t, called, "Handler func should get called") }
func Test_FileNode_Add(t *testing.T) { node0 := NewFileNode("foo/bar") node1 := NewFileNode("foo/baz") obj0 := types.MakeFuString(".c") obj1 := types.MakeStringList("a", "b") var err error var expect types.FuObject var actual types.FuObject // node + node = list of nodes expect = types.MakeFuList(node0, node1) actual, err = node0.Add(node1) assert.Nil(t, err) assert.True(t, expect.Equal(actual)) // node + string = new node expect = NewFileNode("foo/bar.c") actual, err = node0.Add(obj0) assert.Nil(t, err) assert.True(t, expect.Equal(actual)) // node + list = flattened list expect = types.MakeFuList( node0, types.MakeFuString("a"), types.MakeFuString("b")) actual, err = node0.Add(obj1) assert.Nil(t, err) assert.True(t, expect.Equal(actual)) }
func TestGame_IsOver(t *testing.T) { var game Game = NewGame() var board = game.Board() t.Log("New Game is not over") assert.False(t, game.IsOver()) t.Log("Game with two-in-a-row is not over") AddMarks(board, "X", 4, 8) assert.False(t, game.IsOver()) t.Log("Game with three-in-a-row \"X\" is over") board.Mark(0, "X") assert.True(t, game.IsOver()) t.Log("Game with three-in-a-row \"O\" is over") board.Reset() AddMarks(board, "O", 2, 4, 6) assert.True(t, game.IsOver()) t.Log("Game with three-in-a-row mismatched is not over") board.Mark(2, "X") assert.False(t, game.IsOver()) t.Log("Game with nearly-full, non-winning board is not over") board.Reset() AddMarks(board, "X", 0, 1, 4, 5) AddMarks(board, "O", 2, 3, 7, 8) assert.False(t, game.IsOver()) t.Log("Game with full, non-winning board is over") board.Mark(6, "X") assert.True(t, game.IsOver()) }
func Test_ASTInline_Equal(t *testing.T) { node1 := &ASTInline{} node2 := &ASTInline{} assert.True(t, node1.Equal(node1), "ASTInline not equal to itself") assert.True(t, node1.Equal(node2), "empty ASTInlines not equal") node1.lang = "foo" node2.lang = "bar" assert.False(t, node1.Equal(node2), "ASTInlines equal despite different lang") node2.lang = "foo" assert.True(t, node1.Equal(node2), "ASTInlines not equal") node1.content = "hello\nworld\n" node2.content = "hello\nworld" assert.False(t, node1.Equal(node2), "ASTInlines equal despite different content") node2.content += "\n" assert.True(t, node1.Equal(node2), "ASTInlines not equal") }
func Test_PythonPlugin_Run(t *testing.T) { pp, err := NewPythonPlugin() testutils.NoError(t, err) values, err := pp.Run(` import os foo = ["abc", "def"] bar = "!".join(foo) def visible(): pass def _hidden(): pass pjoin = os.path.join `) testutils.NoError(t, err) for _, name := range []string{"os", "foo", "bar", "_hidden", "basdf"} { value, ok := values.Lookup(name) assert.True(t, value == nil && !ok, "expected nothing for name '%s', but got: %v (%T)", name, value, value) } for _, name := range []string{"visible", "pjoin"} { value, ok := values.Lookup(name) callable := value.(PythonCallable) assert.True(t, ok && callable.Name() == name, "expected a PythonCallable for name '%s'", name) } values, err = pp.Run("foo = 1/0") assert.Equal(t, "inline Python plugin raised an exception", err.Error()) }
func Test_CreateDeleteFile(t *testing.T) { test_dir := os.TempDir() file_store, err := New(test_dir) if err != nil { assert.Fail(t, fmt.Sprintf("file store failed to create: %s", err)) } full_test_path := "" // Create file test_file := `invalid/\:jargon` file, err := file_store.OpenFile(test_file, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) assert.True(t, err == nil, fmt.Sprintf("%s", err)) if file != nil { t.Logf("File generated \"%s\" from \"%s\"", file.Name(), test_file) assert.Equal(t, test_file, file.Original_Name(), fmt.Sprintf("File mapping name mismatch, original name %s, original name on file %s", test_file, file.Original_Name())) full_test_path = file.Name() file.Close() } // Delete file err = file_store.DeleteFile(test_file) assert.True(t, err == nil, fmt.Sprintf("%s", err)) _, exist_err := os.Stat(full_test_path) assert.True(t, exist_err != nil) // Cleanup in failure case if err != nil { os.Remove(full_test_path) } }
func Test_ASTRoot_Phase(t *testing.T) { root := &ASTRoot{ children: []ASTNode{ &ASTImport{}, &ASTPhase{name: "meep"}, &ASTInline{}, &ASTPhase{name: "meep"}, // duplicate is invisible &ASTPhase{name: "bong"}, }} var expect *ASTPhase var actual *ASTPhase actual = root.FindPhase("main") assert.Nil(t, actual) expect = root.children[1].(*ASTPhase) actual = root.FindPhase("meep") assert.True(t, expect == actual, "expected %p (%v)\nbut got %p (%v)", expect, expect, actual, actual) expect = root.children[4].(*ASTPhase) actual = root.FindPhase("bong") assert.True(t, expect == actual, "expected %p\n%#v\nbut got %p\n%#v", expect, expect, actual, actual) }
func Test_InvalidPathNew(t *testing.T) { invalid_path := "barf" file_store, err := New(invalid_path) assert.True(t, err != nil, fmt.Sprintf("Accepted bogus path: %s", err)) assert.True(t, file_store == nil, fmt.Sprintf("No nil on error: %s", err)) }
func Test_PythonCallable_callPython(t *testing.T) { plugin, err := NewPythonPlugin() testutils.NoError(t, err) // Setup: define a Python function and make sure that Run() finds // it, so it can be added to a Fubsy namespace and used from Fubsy // code. pycode := ` def reverse_strings(*args): '''takes N strings, reverses each one, then returns the reversed strings concatenated into a single string with + between each one''' return '+'.join(''.join(reversed(arg)) for arg in args)` values, err := plugin.Run(pycode) testutils.NoError(t, err) value, ok := values.Lookup("reverse_strings") assert.True(t, ok) pycallable := value.(PythonCallable) assert.Equal(t, "reverse_strings", pycallable.Name()) // Call the Python function with 3 strings. args := types.MakeStringList("foo", "blob", "pingpong").List() argsource := types.MakeBasicArgs(nil, args, nil) value, errs := pycallable.callPython(argsource) testutils.NoErrors(t, errs) // And test the returned value. expect := types.MakeFuString("oof+bolb+gnopgnip") assert.True(t, expect.Equal(value), "expected %s, but got %s", expect, value) }
func TestMapStaticFile(t *testing.T) { codecService := new(codecservices.WebCodecService) h := NewHttpHandler(codecService) h.MapStaticFile("/static-file", "/location/of/static-file") assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) if assert.Equal(t, 1, len(staticHandler.HttpMethods)) { assert.Equal(t, goweb_http.MethodGet, staticHandler.HttpMethods[0]) } var ctx context.Context var willHandle bool ctx = context_test.MakeTestContextWithPath("/static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("static-file/something-else") willHandle, _ = staticHandler.WillHandle(ctx) assert.False(t, willHandle, "Static handler NOT should handle") }
func assertPathMatchHandler(t *testing.T, handler *PathMatchHandler, path, method string, message string) bool { if assert.NotNil(t, handler) { ctx := context_test.MakeTestContextWithDetails(path, method) willHandle, _ := handler.WillHandle(ctx) if assert.True(t, willHandle, fmt.Sprintf("This handler is expected to handle it: %s", message)) { // make sure the method is in the list methodFound := false for _, methodInList := range handler.HttpMethods { if methodInList == method { methodFound = true break } } return assert.True(t, methodFound, "Method (%s) should be in the method list (%s)", method, handler.HttpMethods) } } return false }
func TestResultNext(t *testing.T) { r := testResult() assert.Equal(t, len(r.Rows), 3) assert.True(t, r.Next()) assert.True(t, r.Next()) assert.True(t, r.Next()) assert.False(t, r.Next()) }
func Test_FinderNode_Equal(t *testing.T) { finder1 := NewFinderNode("*.c", "*.h") finder2 := NewFinderNode("*.c", "*.h") finder3 := NewFinderNode("*.h", "*.c") assert.True(t, finder1.Equal(finder1)) assert.True(t, finder1.Equal(finder2)) assert.False(t, finder1.Equal(finder3)) }
func Test_FinderNode_Lookup(t *testing.T) { node := NewFinderNode("*.txt") val, ok := node.Lookup("foo") assert.Nil(t, val) assert.False(t, ok) val, ok = node.Lookup("prune") code := val.(*types.FuFunction).Code() assert.True(t, code != nil) // argh: cannot compare function pointers! assert.True(t, ok) }
func Test_Mock_AssertNumberOfCalls(t *testing.T) { var mockedService *TestExampleImplementation = new(TestExampleImplementation) mockedService.Mock.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7) mockedService.Mock.Called(1, 2, 3) assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 1)) mockedService.Mock.Called(1, 2, 3) assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 2)) }
func TestMapStatic(t *testing.T) { codecService := new(codecservices.WebCodecService) h := NewHttpHandler(codecService) h.MapStatic("/static", "/location/of/static") assert.Equal(t, 1, len(h.HandlersPipe())) staticHandler := h.HandlersPipe()[0].(*PathMatchHandler) if assert.Equal(t, 1, len(staticHandler.HttpMethods)) { assert.Equal(t, goweb_http.MethodGet, staticHandler.HttpMethods[0]) } var ctx context.Context var willHandle bool ctx = context_test.MakeTestContextWithPath("/static/some/deep/file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/../static/some/deep/file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/some/../file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/../file.dat") willHandle, _ = staticHandler.WillHandle(ctx) assert.False(t, willHandle, "Static handler should not handle") ctx = context_test.MakeTestContextWithPath("/static") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/") willHandle, _ = staticHandler.WillHandle(ctx) assert.True(t, willHandle, "Static handler should handle") ctx = context_test.MakeTestContextWithPath("/static/doc.go") willHandle, _ = staticHandler.WillHandle(ctx) _, staticHandleErr := staticHandler.Handle(ctx) if assert.NoError(t, staticHandleErr) { } }
func Test_checkActions_bad(t *testing.T) { // ensure that one of the bad nodes has location info so we can // test that SemanticError.Error() includes it fileinfo := &fileinfo{"foo.fubsy", []int{0, 10, 15, 16, 20}} location := FileLocation{fileinfo, 11, 18} // line 2-4 nodes := []ASTNode{ &ASTString{value: "foo bar"}, // good &ASTFileFinder{patterns: []string{"*.java"}}, // bad &ASTFunctionCall{}, // good &ASTBuildRule{ // bad astbase: astbase{location}, targets: &ASTString{value: "target"}, sources: &ASTString{value: "source"}, children: []ASTNode{}, }, // hmmm: lots of expressions evaluate to a string -- why can't // I say cmd = "cc -o foo foo.c" outside a build rule, and then // reference cmd inside the build rule? &ASTName{name: "blah"}, // bad (currently) } expect_actions := []ASTNode{ nodes[0], nodes[2], } expect_errors := []SemanticError{ SemanticError{node: nodes[1]}, SemanticError{node: nodes[3]}, SemanticError{node: nodes[4]}, } actions, errors := checkActions(nodes) assert.True(t, len(expect_errors) == len(errors), "expected %d errors, but got %d: %v", len(expect_errors), len(errors), errors) for i, err := range expect_errors { enode := err.node anode := errors[i].(SemanticError).node assert.True(t, anode.Equal(enode), "bad node %d: expected\n%T %p\nbut got\n%T %p", i, enode, enode, anode, anode) } expect_message := "foo.fubsy:2-4: invalid build action: must be either bare string, function call, or variable assignment" actual_message := errors[1].Error() assert.Equal(t, expect_message, actual_message) assert.True(t, reflect.DeepEqual(expect_actions, actions), "expected actions:\n%#v\nbut got:\n%#v", expect_actions, actions) }
func TestSpResultNextResult(t *testing.T) { r := NewSpResult() r1 := testResult() r2 := testResult() r.results = []*Result{r1, r2} assert.Equal(t, 2, r.ResultsCount()) assert.True(t, r.HasResults()) assert.True(t, r.NextResult()) assert.True(t, r1 == r.Result()) assert.True(t, r.NextResult()) assert.True(t, r2 == r.Result()) assert.False(t, r.NextResult()) assert.Nil(t, r.Result()) }
func Test_Record_basics(t *testing.T) { record := NewBuildRecord() assert.True(t, record.SourceSignature("foo") == nil) assert.True(t, record.SourceSignature("bar") == nil) record.AddParent("foo", []byte{0}) record.AddParent("bar", []byte{}) sig := record.SourceSignature("foo") assert.True(t, sig != nil && len(sig) == 1 && sig[0] == 0) sig = record.SourceSignature("bar") assert.True(t, sig != nil && len(sig) == 0) sig = record.SourceSignature("qux") assert.True(t, sig == nil) }
func TestSetMasks(t *testing.T) { m := new(Masks) assert.False(t, m.Grayscale) m.Set(0x01) assert.True(t, m.Grayscale) assert.False(t, m.ShowBackgroundLeft) m.Set(0x02) assert.True(t, m.ShowBackgroundLeft) assert.False(t, m.ShowSpritesLeft) m.Set(0x04) assert.True(t, m.ShowSpritesLeft) assert.False(t, m.ShowBackground) m.Set(0x08) assert.True(t, m.ShowBackground) assert.False(t, m.ShowSprites) m.Set(0x10) assert.True(t, m.ShowSprites) assert.False(t, m.IntenseReds) m.Set(0x20) assert.True(t, m.IntenseReds) assert.False(t, m.IntenseGreens) m.Set(0x40) assert.True(t, m.IntenseGreens) assert.False(t, m.IntenseBlues) m.Set(0x80) assert.True(t, m.IntenseBlues) }
func Test_MakeFileNode(t *testing.T) { dag := NewDAG() node0 := MakeFileNode(dag, "foo") assert.Equal(t, node0.name, "foo") assert.True(t, dag.nodes[0] == node0) assert.True(t, dag.index["foo"] == 0) node1 := MakeFileNode(dag, "bar") assert.Equal(t, node1.name, "bar") assert.True(t, dag.nodes[1] == node1) assert.True(t, dag.index["bar"] == 1) node0b := MakeFileNode(dag, "foo") assert.True(t, node0 == node0b) }
func Test_Arguments_Assert(t *testing.T) { var args Arguments = []interface{}{"string", 123, true} assert.True(t, args.Assert(t, "string", 123, true)) }
// hmmmm: interface-wise, this tests that FinderNode.Add() returns an // object whose CommandString() behaves sensibly... but in // implementation terms, it's really a test of FuList.CommandString() func Test_FinderNode_Add_CommandString(t *testing.T) { finder1 := NewFinderNode("*.c", "*.h") finder2 := NewFinderNode("doc/???.txt") finder3 := NewFinderNode() sum1, err := finder1.Add(finder2) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt'", sum1.CommandString()) sum2, err := finder3.Add(sum1) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt'", sum2.CommandString()) assert.False(t, sum1.Equal(sum2)) sum2b, err := finder3.Add(sum1) assert.Nil(t, err) assert.True(t, sum2.Equal(sum2b), "expected equal ListNodes:\nsum2 = %T %v\nsum2b = %T %v", sum2, sum2, sum2b, sum2b) // This is a silly thing to do, and perhaps we should filter out // the duplicate patterns... but I don't think so. If the user // constructs something silly, we do something silly. sum3, err := sum1.Add(sum2) assert.Nil(t, err) assert.Equal(t, "'*.c' '*.h' 'doc/???.txt' '*.c' '*.h' 'doc/???.txt'", sum3.CommandString()) }
func TestPathMatchHandler_BreakCurrentPipeline(t *testing.T) { pathPattern, _ := paths.NewPathPattern("collection/{id}/name") h := NewPathMatchHandler(pathPattern, HandlerExecutionFunc(func(c context.Context) error { return nil })) h.BreakCurrentPipeline = true ctx1 := context_test.MakeTestContextWithPath("/collection/123/name") breakCurrentPipeline, _ := h.Handle(ctx1) assert.True(t, breakCurrentPipeline) h = NewPathMatchHandler(pathPattern, HandlerExecutionFunc(func(c context.Context) error { return nil })) h.BreakCurrentPipeline = false ctx1 = context_test.MakeTestContextWithPath("/collection/123/name") breakCurrentPipeline, _ = h.Handle(ctx1) assert.False(t, breakCurrentPipeline) }
func TestExecSpInputParams2(t *testing.T) { conn := ConnectToTestDb(t) err := createProcedure(conn, "test_input_params2", "@p1 nvarchar(255), @p2 varchar(255), @p3 nvarchar(255), @p4 nchar(10), @p5 varbinary(10) as select @p1, @p2, @p3, @p4, @p5; return") assert.Nil(t, err) want := "£¢§‹›†€" wantp2 := "abc" wantp3 := "šđčćžabc" wantp4 := "šđčćžabcde" wantp3 = "FK Ventspils v Nõmme Kalju FC" wantp5 := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} rst, err := conn.ExecSp("test_input_params2", want, wantp2, wantp3, wantp4, wantp5) assert.Nil(t, err) assert.NotNil(t, rst) if rst == nil { return } assert.True(t, rst.HasResults()) var got, gotp2, gotp3, gotp4 string var gotp5 []byte result := rst.results[0] result.Next() result.Scan(&got, &gotp2, &gotp3, &gotp4, &gotp5) assert.Equal(t, want, got) assert.Equal(t, wantp2, gotp2) assert.Equal(t, wantp3, gotp3) assert.Equal(t, wantp4, gotp4) assert.Equal(t, wantp5, gotp5) //PrintResults(rst.Results) }
func assertLines(t *testing.T, start int, end int, location FileLocation) { actualstart, actualend := location.linerange() assert.True(t, start == actualstart && end == actualend, "bad location.linerange(): "+ "expected (%d, %d) but got (%d, %d)", start, end, actualstart, actualend) }
// AssertCalled asserts that the method was called. func (m *Mock) AssertCalled(t *testing.T, methodName string, arguments ...interface{}) bool { if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) { t.Logf("%s", m.ExpectedCalls) return false } return true }
func Test_BuiltinList(t *testing.T) { blist := BuiltinList{} fn, ok := blist.Lookup("foo") assert.False(t, ok) assert.Nil(t, fn) callable := types.NewFixedFunction("foo", 3, nil) blist.builtins = append(blist.builtins, callable) fn, ok = blist.Lookup("foo") assert.True(t, ok) assert.Equal(t, callable, fn) blist.builtins = append( blist.builtins, types.NewFixedFunction("bar", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("bop", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("bam", 0, nil)) blist.builtins = append( blist.builtins, types.NewFixedFunction("pow", 0, nil)) assert.Equal(t, 5, blist.NumBuiltins()) actual := make([]string, 0, 5) visit := func(name string, code types.FuObject) error { actual = append(actual, name) if name == "bam" { return errors.New("bam!") } return nil } err := blist.ForEach(visit) assert.Equal(t, []string{"foo", "bar", "bop", "bam"}, actual) assert.Equal(t, "bam!", err.Error()) }