1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package bigquery
15
16import (
17	"fmt"
18	"testing"
19	"time"
20
21	"cloud.google.com/go/internal/testutil"
22	bq "google.golang.org/api/bigquery/v2"
23)
24
25func testRoutineConversion(t *testing.T, conversion string, in interface{}, want interface{}) {
26	var got interface{}
27	var err error
28	switch conversion {
29	case "ToRoutineMetadata":
30		input, ok := in.(*bq.Routine)
31		if !ok {
32			t.Fatalf("failed input type conversion (bq.Routine): %v", in)
33		}
34		got, err = bqToRoutineMetadata(input)
35	case "FromRoutineMetadataToUpdate":
36		input, ok := in.(*RoutineMetadataToUpdate)
37		if !ok {
38			t.Fatalf("failed input type conversion: %v", in)
39		}
40		got, err = input.toBQ()
41	case "ToRoutineArgument":
42		input, ok := in.(*bq.Argument)
43		if !ok {
44			t.Fatalf("failed input type conversion: %v", in)
45		}
46		got, err = bqToRoutineArgument(input)
47	case "FromRoutineArgument":
48		input, ok := in.(*RoutineArgument)
49		if !ok {
50			t.Fatalf("failed input type conversion: %v", in)
51		}
52		got, err = input.toBQ()
53	default:
54		t.Fatalf("invalid comparison: %s", conversion)
55	}
56
57	if err != nil {
58		t.Fatalf("failed conversion function for %q", conversion)
59	}
60	if diff := testutil.Diff(got, want); diff != "" {
61		t.Fatalf("%+v: -got, +want:\n%s", in, diff)
62	}
63}
64
65func TestRoutineTypeConversions(t *testing.T) {
66	aTime := time.Date(2019, 3, 14, 0, 0, 0, 0, time.Local)
67	aTimeMillis := aTime.UnixNano() / 1e6
68
69	tests := []struct {
70		name       string
71		conversion string
72		in         interface{}
73		want       interface{}
74	}{
75		{"empty", "ToRoutineMetadata", &bq.Routine{}, &RoutineMetadata{}},
76		{"basic", "ToRoutineMetadata",
77			&bq.Routine{
78				CreationTime:     aTimeMillis,
79				LastModifiedTime: aTimeMillis,
80				DefinitionBody:   "body",
81				Description:      "desc",
82				Etag:             "etag",
83				RoutineType:      "type",
84				Language:         "lang",
85			},
86			&RoutineMetadata{
87				CreationTime:     aTime,
88				LastModifiedTime: aTime,
89				Description:      "desc",
90				Body:             "body",
91				ETag:             "etag",
92				Type:             "type",
93				Language:         "lang",
94			}},
95		{"body_and_libs", "FromRoutineMetadataToUpdate",
96			&RoutineMetadataToUpdate{
97				Body:              "body",
98				ImportedLibraries: []string{"foo", "bar"},
99			},
100			&bq.Routine{
101				DefinitionBody:    "body",
102				ImportedLibraries: []string{"foo", "bar"},
103				ForceSendFields:   []string{"DefinitionBody", "ImportedLibraries"},
104			}},
105		{"null_fields", "FromRoutineMetadataToUpdate",
106			&RoutineMetadataToUpdate{
107				Type:              "type",
108				Arguments:         []*RoutineArgument{},
109				ImportedLibraries: []string{},
110			},
111			&bq.Routine{
112				RoutineType:     "type",
113				ForceSendFields: []string{"RoutineType"},
114				NullFields:      []string{"Arguments", "ImportedLibraries"},
115			}},
116		{"empty", "ToRoutineArgument",
117			&bq.Argument{},
118			&RoutineArgument{}},
119		{"basic", "ToRoutineArgument",
120			&bq.Argument{
121				Name:         "foo",
122				ArgumentKind: "bar",
123				Mode:         "baz",
124			},
125			&RoutineArgument{
126				Name: "foo",
127				Kind: "bar",
128				Mode: "baz",
129			}},
130		{"empty", "FromRoutineArgument",
131			&RoutineArgument{},
132			&bq.Argument{},
133		},
134		{"basic", "FromRoutineArgument",
135			&RoutineArgument{
136				Name: "foo",
137				Kind: "bar",
138				Mode: "baz",
139			},
140			&bq.Argument{
141				Name:         "foo",
142				ArgumentKind: "bar",
143				Mode:         "baz",
144			}},
145	}
146
147	for _, test := range tests {
148		t.Run(fmt.Sprintf("%s/%s", test.conversion, test.name), func(t *testing.T) {
149			t.Parallel()
150			testRoutineConversion(t, test.conversion, test.in, test.want)
151		})
152	}
153}
154