1// Copyright 2017 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. 14 15package bigquery 16 17import ( 18 "testing" 19 20 "cloud.google.com/go/internal/pretty" 21 "cloud.google.com/go/internal/testutil" 22) 23 24func TestExternalDataConfig(t *testing.T) { 25 // Round-trip of ExternalDataConfig to underlying representation. 26 for i, want := range []*ExternalDataConfig{ 27 { 28 SourceFormat: CSV, 29 SourceURIs: []string{"uri"}, 30 Schema: Schema{{Name: "n", Type: IntegerFieldType}}, 31 AutoDetect: true, 32 Compression: Gzip, 33 IgnoreUnknownValues: true, 34 MaxBadRecords: 17, 35 Options: &CSVOptions{ 36 AllowJaggedRows: true, 37 AllowQuotedNewlines: true, 38 Encoding: UTF_8, 39 FieldDelimiter: "f", 40 Quote: "q", 41 SkipLeadingRows: 3, 42 }, 43 }, 44 { 45 SourceFormat: GoogleSheets, 46 Options: &GoogleSheetsOptions{SkipLeadingRows: 4}, 47 }, 48 { 49 SourceFormat: Bigtable, 50 Options: &BigtableOptions{ 51 IgnoreUnspecifiedColumnFamilies: true, 52 ReadRowkeyAsString: true, 53 ColumnFamilies: []*BigtableColumnFamily{ 54 { 55 FamilyID: "f1", 56 Encoding: "TEXT", 57 OnlyReadLatest: true, 58 Type: "FLOAT", 59 Columns: []*BigtableColumn{ 60 { 61 Qualifier: "valid-utf-8", 62 FieldName: "fn", 63 OnlyReadLatest: true, 64 Encoding: "BINARY", 65 Type: "STRING", 66 }, 67 }, 68 }, 69 }, 70 }, 71 }, 72 } { 73 q := want.toBQ() 74 got, err := bqToExternalDataConfig(&q) 75 if err != nil { 76 t.Fatal(err) 77 } 78 if diff := testutil.Diff(got, want); diff != "" { 79 t.Errorf("#%d: got=-, want=+:\n%s", i, diff) 80 } 81 } 82} 83 84func TestQuote(t *testing.T) { 85 ptr := func(s string) *string { return &s } 86 87 for _, test := range []struct { 88 quote string 89 force bool 90 want *string 91 }{ 92 {"", false, nil}, 93 {"", true, ptr("")}, 94 {"-", false, ptr("-")}, 95 {"-", true, ptr("")}, 96 } { 97 o := CSVOptions{ 98 Quote: test.quote, 99 ForceZeroQuote: test.force, 100 } 101 got := o.quote() 102 if (got == nil) != (test.want == nil) { 103 t.Errorf("%+v\ngot %v\nwant %v", test, pretty.Value(got), pretty.Value(test.want)) 104 } 105 if got != nil && test.want != nil && *got != *test.want { 106 t.Errorf("%+v: got %q, want %q", test, *got, *test.want) 107 } 108 } 109} 110 111func TestQualifier(t *testing.T) { 112 b := BigtableColumn{Qualifier: "a"} 113 q := b.toBQ() 114 if q.QualifierString != b.Qualifier || q.QualifierEncoded != "" { 115 t.Errorf("got (%q, %q), want (%q, %q)", 116 q.QualifierString, q.QualifierEncoded, b.Qualifier, "") 117 } 118 b2, err := bqToBigtableColumn(q) 119 if err != nil { 120 t.Fatal(err) 121 } 122 if got, want := b2.Qualifier, b.Qualifier; got != want { 123 t.Errorf("got %q, want %q", got, want) 124 } 125 126 const ( 127 invalidUTF8 = "\xDF\xFF" 128 invalidEncoded = "3/8" 129 ) 130 b = BigtableColumn{Qualifier: invalidUTF8} 131 q = b.toBQ() 132 if q.QualifierString != "" || q.QualifierEncoded != invalidEncoded { 133 t.Errorf("got (%q, %q), want (%q, %q)", 134 q.QualifierString, "", b.Qualifier, invalidEncoded) 135 } 136 b2, err = bqToBigtableColumn(q) 137 if err != nil { 138 t.Fatal(err) 139 } 140 if got, want := b2.Qualifier, b.Qualifier; got != want { 141 t.Errorf("got %q, want %q", got, want) 142 } 143} 144