|
- // Copyright 2017, Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- package vision
-
- import (
- "fmt"
- "reflect"
- "testing"
-
- "github.com/golang/protobuf/proto"
- "golang.org/x/net/context"
- pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
- "google.golang.org/genproto/googleapis/rpc/status"
- "google.golang.org/grpc"
- "google.golang.org/grpc/codes"
- )
-
- var batchResponse = &pb.BatchAnnotateImagesResponse{
- Responses: []*pb.AnnotateImageResponse{{
- FaceAnnotations: []*pb.FaceAnnotation{
- {RollAngle: 1}, {RollAngle: 2}},
- LandmarkAnnotations: []*pb.EntityAnnotation{{Mid: "landmark"}},
- LogoAnnotations: []*pb.EntityAnnotation{{Mid: "logo"}},
- LabelAnnotations: []*pb.EntityAnnotation{{Mid: "label"}},
- TextAnnotations: []*pb.EntityAnnotation{{Mid: "text"}},
- FullTextAnnotation: &pb.TextAnnotation{Text: "full"},
- SafeSearchAnnotation: &pb.SafeSearchAnnotation{Spoof: pb.Likelihood_POSSIBLE},
- ImagePropertiesAnnotation: &pb.ImageProperties{DominantColors: &pb.DominantColorsAnnotation{}},
- CropHintsAnnotation: &pb.CropHintsAnnotation{CropHints: []*pb.CropHint{{Confidence: 0.5}}},
- WebDetection: &pb.WebDetection{WebEntities: []*pb.WebDetection_WebEntity{{EntityId: "web"}}},
- }},
- }
-
- // Verify that all the "shortcut" methods use the underlying
- // BatchAnnotateImages RPC correctly.
- func TestClientMethods(t *testing.T) {
- ctx := context.Background()
- c, err := NewImageAnnotatorClient(ctx, clientOpt)
- if err != nil {
- t.Fatal(err)
- }
-
- mockImageAnnotator.resps = []proto.Message{batchResponse}
- img := &pb.Image{Source: &pb.ImageSource{ImageUri: "http://foo.jpg"}}
- ictx := &pb.ImageContext{LanguageHints: []string{"en", "fr"}}
- req := &pb.AnnotateImageRequest{
- Image: img,
- ImageContext: ictx,
- Features: []*pb.Feature{
- {Type: pb.Feature_LABEL_DETECTION, MaxResults: 3},
- {Type: pb.Feature_FACE_DETECTION, MaxResults: 4},
- },
- }
-
- for i, test := range []struct {
- call func() (interface{}, error)
- wantFeatures []*pb.Feature
- wantRes interface{}
- }{
- {
- func() (interface{}, error) { return c.AnnotateImage(ctx, req) },
- req.Features, batchResponse.Responses[0],
- },
- {
- func() (interface{}, error) { return c.DetectFaces(ctx, img, ictx, 2) },
- []*pb.Feature{{Type: pb.Feature_FACE_DETECTION, MaxResults: 2}},
- batchResponse.Responses[0].FaceAnnotations,
- },
- {
- func() (interface{}, error) { return c.DetectLandmarks(ctx, img, ictx, 2) },
- []*pb.Feature{{Type: pb.Feature_LANDMARK_DETECTION, MaxResults: 2}},
- batchResponse.Responses[0].LandmarkAnnotations,
- },
- {
- func() (interface{}, error) { return c.DetectLogos(ctx, img, ictx, 2) },
- []*pb.Feature{{Type: pb.Feature_LOGO_DETECTION, MaxResults: 2}},
- batchResponse.Responses[0].LogoAnnotations,
- },
- {
- func() (interface{}, error) { return c.DetectLabels(ctx, img, ictx, 2) },
- []*pb.Feature{{Type: pb.Feature_LABEL_DETECTION, MaxResults: 2}},
- batchResponse.Responses[0].LabelAnnotations,
- },
- {
- func() (interface{}, error) { return c.DetectTexts(ctx, img, ictx, 2) },
- []*pb.Feature{{Type: pb.Feature_TEXT_DETECTION, MaxResults: 2}},
- batchResponse.Responses[0].TextAnnotations,
- },
- {
- func() (interface{}, error) { return c.DetectDocumentText(ctx, img, ictx) },
- []*pb.Feature{{Type: pb.Feature_DOCUMENT_TEXT_DETECTION, MaxResults: 0}},
- batchResponse.Responses[0].FullTextAnnotation,
- },
- {
- func() (interface{}, error) { return c.DetectSafeSearch(ctx, img, ictx) },
- []*pb.Feature{{Type: pb.Feature_SAFE_SEARCH_DETECTION, MaxResults: 0}},
- batchResponse.Responses[0].SafeSearchAnnotation,
- },
- {
- func() (interface{}, error) { return c.DetectImageProperties(ctx, img, ictx) },
- []*pb.Feature{{Type: pb.Feature_IMAGE_PROPERTIES, MaxResults: 0}},
- batchResponse.Responses[0].ImagePropertiesAnnotation,
- },
- {
- func() (interface{}, error) { return c.DetectWeb(ctx, img, ictx) },
- []*pb.Feature{{Type: pb.Feature_WEB_DETECTION, MaxResults: 0}},
- batchResponse.Responses[0].WebDetection,
- },
- {
- func() (interface{}, error) { return c.CropHints(ctx, img, ictx) },
- []*pb.Feature{{Type: pb.Feature_CROP_HINTS, MaxResults: 0}},
- batchResponse.Responses[0].CropHintsAnnotation,
- },
- } {
- mockImageAnnotator.reqs = nil
- res, err := test.call()
- if err != nil {
- t.Fatal(err)
- }
- got := mockImageAnnotator.reqs[0]
- want := &pb.BatchAnnotateImagesRequest{
- Requests: []*pb.AnnotateImageRequest{{
- Image: img,
- ImageContext: ictx,
- Features: test.wantFeatures,
- }},
- }
- if !testEqual(got, want) {
- t.Errorf("#%d:\ngot %v\nwant %v", i, got, want)
- }
- if got, want := res, test.wantRes; !testEqual(got, want) {
- t.Errorf("#%d:\ngot %v\nwant %v", i, got, want)
- }
- }
-
- }
-
- func testEqual(a, b interface{}) bool {
- if a == nil && b == nil {
- return true
- }
- if a == nil || b == nil {
- return false
- }
- t := reflect.TypeOf(a)
- if t != reflect.TypeOf(b) {
- return false
- }
- if am, ok := a.(proto.Message); ok {
- return proto.Equal(am, b.(proto.Message))
- }
- if t.Kind() != reflect.Slice {
- panic(fmt.Sprintf("testEqual can only handle proto.Message and slices, got %s", t))
- }
- va := reflect.ValueOf(a)
- vb := reflect.ValueOf(b)
- if va.Len() != vb.Len() {
- return false
- }
- for i := 0; i < va.Len(); i++ {
- if !testEqual(va.Index(i).Interface(), vb.Index(i).Interface()) {
- return false
- }
- }
- return true
- }
-
- func TestAnnotateOneError(t *testing.T) {
- ctx := context.Background()
- c, err := NewImageAnnotatorClient(ctx, clientOpt)
- if err != nil {
- t.Fatal(err)
- }
- mockImageAnnotator.resps = []proto.Message{
- &pb.BatchAnnotateImagesResponse{
- Responses: []*pb.AnnotateImageResponse{{
- Error: &status.Status{Code: int32(codes.NotFound), Message: "not found"},
- }},
- },
- }
-
- _, err = c.annotateOne(ctx,
- &pb.Image{Source: &pb.ImageSource{ImageUri: "http://foo.jpg"}},
- nil, pb.Feature_LOGO_DETECTION, 1, nil)
- if c := grpc.Code(err); c != codes.NotFound {
- t.Errorf("got %v, want NotFound", c)
- }
- }
|