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{ 47 SkipLeadingRows: 4, 48 Range: "sheet1!A1:Z10", 49 }, 50 }, 51 { 52 SourceFormat: Bigtable, 53 Options: &BigtableOptions{ 54 IgnoreUnspecifiedColumnFamilies: true, 55 ReadRowkeyAsString: true, 56 ColumnFamilies: []*BigtableColumnFamily{ 57 { 58 FamilyID: "f1", 59 Encoding: "TEXT", 60 OnlyReadLatest: true, 61 Type: "FLOAT", 62 Columns: []*BigtableColumn{ 63 { 64 Qualifier: "valid-utf-8", 65 FieldName: "fn", 66 OnlyReadLatest: true, 67 Encoding: "BINARY", 68 Type: "STRING", 69 }, 70 }, 71 }, 72 }, 73 }, 74 }, 75 } { 76 q := want.toBQ() 77 got, err := bqToExternalDataConfig(&q) 78 if err != nil { 79 t.Fatal(err) 80 } 81 if diff := testutil.Diff(got, want); diff != "" { 82 t.Errorf("#%d: got=-, want=+:\n%s", i, diff) 83 } 84 } 85} 86 87func TestQuote(t *testing.T) { 88 ptr := func(s string) *string { return &s } 89 90 for _, test := range []struct { 91 quote string 92 force bool 93 want *string 94 }{ 95 {"", false, nil}, 96 {"", true, ptr("")}, 97 {"-", false, ptr("-")}, 98 {"-", true, ptr("")}, 99 } { 100 o := CSVOptions{ 101 Quote: test.quote, 102 ForceZeroQuote: test.force, 103 } 104 got := o.quote() 105 if (got == nil) != (test.want == nil) { 106 t.Errorf("%+v\ngot %v\nwant %v", test, pretty.Value(got), pretty.Value(test.want)) 107 } 108 if got != nil && test.want != nil && *got != *test.want { 109 t.Errorf("%+v: got %q, want %q", test, *got, *test.want) 110 } 111 } 112} 113 114func TestQualifier(t *testing.T) { 115 b := BigtableColumn{Qualifier: "a"} 116 q := b.toBQ() 117 if q.QualifierString != b.Qualifier || q.QualifierEncoded != "" { 118 t.Errorf("got (%q, %q), want (%q, %q)", 119 q.QualifierString, q.QualifierEncoded, b.Qualifier, "") 120 } 121 b2, err := bqToBigtableColumn(q) 122 if err != nil { 123 t.Fatal(err) 124 } 125 if got, want := b2.Qualifier, b.Qualifier; got != want { 126 t.Errorf("got %q, want %q", got, want) 127 } 128 129 const ( 130 invalidUTF8 = "\xDF\xFF" 131 invalidEncoded = "3/8" 132 ) 133 b = BigtableColumn{Qualifier: invalidUTF8} 134 q = b.toBQ() 135 if q.QualifierString != "" || q.QualifierEncoded != invalidEncoded { 136 t.Errorf("got (%q, %q), want (%q, %q)", 137 q.QualifierString, "", b.Qualifier, invalidEncoded) 138 } 139 b2, err = bqToBigtableColumn(q) 140 if err != nil { 141 t.Fatal(err) 142 } 143 if got, want := b2.Qualifier, b.Qualifier; got != want { 144 t.Errorf("got %q, want %q", got, want) 145 } 146} 147