Added tests.

Change-Id: I6ed45c0c185702f732d533cf25b3b5d98979ce1a
diff --git a/go/src/v.io/x/ref/services/discovery/ble/neighborhood.go b/go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood.go
similarity index 93%
rename from go/src/v.io/x/ref/services/discovery/ble/neighborhood.go
rename to go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood.go
index 301316a..5f0727c 100644
--- a/go/src/v.io/x/ref/services/discovery/ble/neighborhood.go
+++ b/go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package main
+package lib
 
 import (
 	"bytes"
@@ -161,7 +161,7 @@
 	lastSeen time.Time
 }
 
-type bleNeighborHood struct {
+type BleNeighborHood struct {
 	mu sync.Mutex
 
 	neighborsHashCache map[string]*bleCacheEntry
@@ -178,7 +178,7 @@
 	// the cancel goroutine that it doesn't need to do anything.
 	timeoutMap map[string]chan struct{}
 	// The hash that we use to avoid multiple connections are stored in the
-	// advertising data, so we need to store somewhere in the bleNeighorhood
+	// advertising data, so we need to store somewhere in the BleNeighorhood
 	// until we are ready to save the new device data.  This map is
 	// the keeper of the data.
 	pendingHashMap map[string]string
@@ -188,8 +188,8 @@
 	nextScanId     int64
 }
 
-func newBleNeighborhood(name string) (*bleNeighborHood, error) {
-	b := &bleNeighborHood{
+func newBleNeighborhood(name string) (*BleNeighborHood, error) {
+	b := &BleNeighborHood{
 		neighborsHashCache: make(map[string]*bleCacheEntry),
 		knownNeighbors: make(map[string]*bleCacheEntry),
 		name:               name,
@@ -204,7 +204,7 @@
 	return b, nil
 }
 
-func (b *bleNeighborHood) addService(id string, service ble.Service) {
+func (b *BleNeighborHood) AddService(id string, service ble.Service) {
 	b.mu.Lock()
 	b.services[id] = newService(id, service.InstanceId, service.Attributes)
 	v := make([]*gatt.Service, 0, len(b.services))
@@ -215,7 +215,7 @@
 	b.device.SetServices(v)
 }
 
-func (b *bleNeighborHood) removeService(id string) {
+func (b *BleNeighborHood) RemoveService(id string) {
 	b.mu.Lock()
 	delete(b.services, id)
 	v := make([]*gatt.Service, 0, len(b.services))
@@ -226,7 +226,7 @@
 	b.device.SetServices(v)
 }
 
-func (b *bleNeighborHood) addScanner(uuid *[]byte, attr map[string]string, ch chan *update) int64 {
+func (b *BleNeighborHood) AddScanner(uuid *[]byte, attr map[string]string, ch chan *update) int64 {
 	s := &scanner{
 		attributes: attr,
 		ch:         ch,
@@ -242,7 +242,7 @@
 	return id
 }
 
-func (b *bleNeighborHood) removeScanner(id int64) {
+func (b *BleNeighborHood) removeScanner(id int64) {
 	b.mu.Lock()
 	scanner, found := b.scanners[id]
 	if found {
@@ -252,7 +252,7 @@
 	b.mu.Unlock()
 }
 
-func (b *bleNeighborHood) Stop() error {
+func (b *BleNeighborHood) Stop() error {
 	b.mu.Lock()
 	b.isStopped = true
 	b.mu.Unlock()
@@ -261,7 +261,7 @@
 	return nil
 }
 
-func (b *bleNeighborHood) advertiseAndScan() {
+func (b *BleNeighborHood) advertiseAndScan() {
 	b.mu.Lock()
 	isStopped := b.isStopped
 	b.mu.Unlock()
@@ -275,7 +275,7 @@
 }
 
 // seenHash returns
-func (b *bleNeighborHood) seenHash(id string, h string) bool {
+func (b *BleNeighborHood) seenHash(id string, h string) bool {
 	log.Println("Checking for existence of", h)
 	b.mu.Lock()
 	defer b.mu.Unlock()
@@ -299,7 +299,7 @@
 
 // shouldConnect returns true if a connection should be made to p to get an update on the
 // state of the services on that device.
-func (b *bleNeighborHood) shouldConnect(p gatt.Peripheral, a *gatt.Advertisement) bool {
+func (b *BleNeighborHood) shouldConnect(p gatt.Peripheral, a *gatt.Advertisement) bool {
 	md := a.ManufacturerData
 	// The manufuacture data for other vanadium devices have the format:
 	// 0xe9 0x03 <length> <hash>
@@ -313,7 +313,7 @@
 	return !b.seenHash(p.ID(), hex.EncodeToString(hash))
 }
 
-func (b *bleNeighborHood) getAllServices(p gatt.Peripheral) {
+func (b *BleNeighborHood) getAllServices(p gatt.Peripheral) {
 	log.Println("Connected to device")
 
 	b.mu.Lock()
@@ -398,7 +398,7 @@
 	b.saveDevice(h, p.ID(), name, services)
 }
 
-func (b *bleNeighborHood) startBLEService() error {
+func (b *BleNeighborHood) startBLEService() error {
 	d, err := gatt.NewDevice(gattOptions...)
 	if err != nil {
 		return err
@@ -463,7 +463,7 @@
 	return nil
 }
 
-func (b *bleNeighborHood) saveDevice(hash string, id string, name string, services map[string]*ble.Service) {
+func (b *BleNeighborHood) saveDevice(hash string, id string, name string, services map[string]*ble.Service) {
 	b.mu.Lock()
 	defer b.mu.Unlock()
 	_, found := b.neighborsHashCache[hash]
@@ -504,7 +504,7 @@
 
 }
 
-func (b *bleNeighborHood) computeAdvertisement() *gatt.AdvPacket {
+func (b *BleNeighborHood) computeAdvertisement() *gatt.AdvPacket {
 	// The hash is:
 	// Hash(Hash(name),Hash(b.endpoints))
 	hasher := fnv.New64()
diff --git a/go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood_test.go b/go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood_test.go
new file mode 100644
index 0000000..9b43a6f
--- /dev/null
+++ b/go/src/v.io/x/ref/services/discovery/ble/internal/lib/neighborhood_test.go
@@ -0,0 +1,53 @@
+package lib
+import (
+	"testing"
+	"mojom/v.io/x/ref/services/discovery/ble/ble"
+)
+
+func TestScannerWithUUID(t *testing.T) {
+	scanner := &scanner{
+		uuid: "random-uuid",
+	}
+
+	if scanner.matches("another-uuid", &ble.Service{}) {
+		t.Errorf("Unexpected match for another-uuid")
+	}
+
+	if !scanner.matches("random-uuid", &ble.Service{}) {
+		t.Errorf("should have matched random-uuid")
+	}
+}
+
+func TestScannerWithUUIDAndMap(t *testing.T) {
+	scanner := &scanner{
+		uuid: "random-uuid",
+		attributes: map[string]string{
+			"foo": "bar",
+		},
+	}
+
+	s := &ble.Service{
+		Attributes: map[string]string{
+			"foo": "bar",
+		},
+	}
+
+	if !scanner.matches("random-uuid", s) {
+		t.Errorf("should have matched service:%v", s)
+	}
+
+	if scanner.matches("random-uuid2", s) {
+		t.Errorf("should not have matched service because of uuid")
+	}
+
+	s.Attributes["key2"] = "value"
+
+	if !scanner.matches("random-uuid", s) {
+		t.Errorf("should have matched service:%v", s)
+	}
+
+	s.Attributes["foo"] ="wrong value"
+	if scanner.matches("random-uuid", s) {
+		t.Errorf("should not have matched service:%v", s)
+	}
+}
\ No newline at end of file
diff --git a/go/src/v.io/x/ref/services/discovery/ble/service.go b/go/src/v.io/x/ref/services/discovery/ble/service.go
index bf0a91a..5c98d76 100644
--- a/go/src/v.io/x/ref/services/discovery/ble/service.go
+++ b/go/src/v.io/x/ref/services/discovery/ble/service.go
@@ -10,19 +10,20 @@
 	"mojo/public/go/system"
 
 	"mojom/v.io/x/ref/services/discovery/ble/ble"
+	"v.io/x/ref/services/discovery/ble/internal/lib"
 )
 
 //#include "mojo/public/c/system/types.h"
 import "C"
 
 type bleImpl struct {
-	n *bleNeighborHood
+	n *lib.BleNeighborHood
 	d *delegate
 }
 
 func (b *bleImpl) Advertise(adv ble.Advertisement) (ble.PluginStopper_Pointer, error) {
 	uuid := hex.EncodeToString(adv.ServiceId)
-	b.n.addService(uuid, adv.Service)
+	b.n.AddService(uuid, adv.Service)
 	return b.createHandleFor(&stopAdvertingImpl{uuid: uuid, n: b.n}), nil
 }
 
@@ -38,7 +39,7 @@
 			}
 		}
 	}()
-	id := b.n.addScanner(uuid, attr, ch)
+	id := b.n.AddScanner(uuid, attr, ch)
 	return b.createHandleFor(&stopScanImpl{id: id, n: b.n}), nil
 }