// Copyright 2018 Google Inc. All Rights Reserved. // // 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 datastore import ( "testing" "cloud.google.com/go/internal/testutil" pb "google.golang.org/genproto/googleapis/datastore/v1" ) func TestMutationProtos(t *testing.T) { var keys []*Key for i := 1; i <= 4; i++ { k := IDKey("kind", int64(i), nil) keys = append(keys, k) } entity := &PropertyList{{Name: "n", Value: "v"}} entityForKey := func(k *Key) *pb.Entity { return &pb.Entity{ Key: keyToProto(k), Properties: map[string]*pb.Value{ "n": &pb.Value{ValueType: &pb.Value_StringValue{StringValue: "v"}}, }, } } for _, test := range []struct { desc string in []*Mutation want []*pb.Mutation }{ { desc: "nil", in: nil, want: nil, }, { desc: "empty", in: []*Mutation{}, want: nil, }, { desc: "various", in: []*Mutation{ NewInsert(keys[0], entity), NewUpsert(keys[1], entity), NewUpdate(keys[2], entity), NewDelete(keys[3]), }, want: []*pb.Mutation{ &pb.Mutation{Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[0])}}, &pb.Mutation{Operation: &pb.Mutation_Upsert{Upsert: entityForKey(keys[1])}}, &pb.Mutation{Operation: &pb.Mutation_Update{Update: entityForKey(keys[2])}}, &pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[3])}}, }, }, { desc: "duplicate deletes", in: []*Mutation{ NewDelete(keys[0]), NewInsert(keys[1], entity), NewDelete(keys[0]), NewDelete(keys[2]), NewDelete(keys[0]), }, want: []*pb.Mutation{ &pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[0])}}, &pb.Mutation{Operation: &pb.Mutation_Insert{Insert: entityForKey(keys[1])}}, &pb.Mutation{Operation: &pb.Mutation_Delete{Delete: keyToProto(keys[2])}}, }, }, } { got, err := mutationProtos(test.in) if err != nil { t.Errorf("%s: %v", test.desc, err) continue } if diff := testutil.Diff(got, test.want); diff != "" { t.Errorf("%s: %s", test.desc, diff) } } } func TestMutationProtosErrors(t *testing.T) { entity := &PropertyList{{Name: "n", Value: "v"}} k := IDKey("kind", 1, nil) ik := IncompleteKey("kind", nil) for _, test := range []struct { desc string in []*Mutation want []int // non-nil indexes of MultiError }{ { desc: "invalid key", in: []*Mutation{ NewInsert(nil, entity), NewUpdate(nil, entity), NewUpsert(nil, entity), NewDelete(nil), }, want: []int{0, 1, 2, 3}, }, { desc: "incomplete key", in: []*Mutation{ NewInsert(ik, entity), NewUpdate(ik, entity), NewUpsert(ik, entity), NewDelete(ik), }, want: []int{1, 3}, }, { desc: "bad entity", in: []*Mutation{ NewInsert(k, 1), NewUpdate(k, 2), NewUpsert(k, 3), }, want: []int{0, 1, 2}, }, } { _, err := mutationProtos(test.in) if err == nil { t.Errorf("%s: got nil, want error", test.desc) continue } var got []int for i, err := range err.(MultiError) { if err != nil { got = append(got, i) } } if !testutil.Equal(got, test.want) { t.Errorf("%s: got errors at %v, want at %v", test.desc, got, test.want) } } }