func (upd BabelUpdate) lequal(reader *bufio.Reader, t *testing.T,
	fieldStringHook map[string](func(interface{}) string)) {
	for {
		nextLine, err := reader.ReadString('\n')
		if err != nil {
			t.Fatal(err)
		}
		r := strings.NewReader(nextLine)
		s := NewScanner(r)
		w, err := nextWord(s)
		if err != nil && err != io.EOF && err != errEOL {
			t.Fatal("parser.nextWord:\n", err)
		}
		if err == io.EOF || err == errEOL {
			return
		}
		line := w
		if w != string(upd.action) {
			fmt.Println("Warning: unknown action '" + w +
				"' (skip rest of the line)")
			for {
				w, err = nextWord(s)
				if err != nil && err != io.EOF &&
					err != errEOL {
					t.Fatal("parser.nextWord:\n", err)
				}
				if err == io.EOF || err == errEOL {
					if testing.Verbose() {
						fmt.Println(line)
					}
					break
				}
				line += (" " + w)
			}
			continue
		}
		checkNextWord := func(given string) {
			w, err = nextWord(s)
			if err != nil && err != io.EOF && err != errEOL {
				t.Fatal("parser.nextWord:\n", err)
			}
			if err == io.EOF || err == errEOL {
				if testing.Verbose() {
					fmt.Println(line)
				}
				return
			}
			line += (" " + w)
			if w != given {
				t.Fatal("In the line: ", line,
					"...\n\texpected: ", w,
					"\n\tgiven: ", given)
			}
		}
		checkNextWord(string(upd.tableId))
		checkNextWord(string(upd.entryId))
		for {
			w, err = nextWord(s)
			if err != nil && err != io.EOF && err != errEOL {
				t.Fatal("parser.nextWord:\n", err)
			}
			if err == io.EOF || err == errEOL {
				if testing.Verbose() {
					fmt.Println(line)
				}
				return
			}
			value, exists := upd.entry[Id(w)]
			if !exists {
				t.Fatal("No such field: " + w +
					"\n" + upd.entry.String())
			}
			line += (" " + w)
			w2, err := nextWord(s)
			if err != nil && err != io.EOF && err != errEOL {
				t.Fatal("parser.nextWord:\n", err)
			}
			if err == io.EOF || err == errEOL {
				if testing.Verbose() {
					fmt.Println(line)
				}
				return
			}
			line += (" " + w2)
			hook, exists := fieldStringHook[string(upd.tableId)+
				"_"+w]
			var given string
			if exists {
				given = hook(value.data)
			} else {
				given = fmt.Sprint(value.data)
			}
			if given != w2 {
				t.Fatal("In the line: ", line,
					"...\nexpected: ", w2,
					"\ngiven: ", given)
			}
		}
	}
}
Lexical comparison of the given update with next valid line from `reader`.
`fieldStringHook` associates entry field with 'toString-like' function.
`lequal` uses `nextWord`, which must be tested separately.
`lequal` is ugly and slow, but really simple
(otherwise we need to test our test)
package parser
import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"sync"
	"testing"
)
func TestListen(t *testing.T) {
	r, err := os.Open("monitor")
	if err != nil {
		t.Fatal("os.Open:\n", err)
	}
	s := NewScanner(r)
	bd := NewBabelDesc()
	updChan := make(chan BabelUpdate)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		err = Listen(bd, s, updChan)
		wg.Done()
		close(updChan)
	}()
	r2, err := os.Open("monitor")
	if err != nil {
		t.Fatal("os.Open:\n", err)
	}
	reader := bufio.NewReader(r2)
	fieldStringHook := make(map[string](func(interface{}) string))
	fieldStringHook["neighbour_reach"] = func(v interface{}) string {
		return fmt.Sprintf("%04x", v)
	}
	fieldStringHook["route_installed"] = func(v interface{}) string {
		if b := v.(bool); b {
			return "yes"
		}
		return "no"
	}
	for upd := range updChan {
		upd.lequal(reader, t, fieldStringHook)
		if testing.Verbose() {
			fmt.Print(upd)
		}
	}
	wg.Wait()
	if err != nil {
		t.Fatal("parser.Listen:\n", err)
	}
}