value_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // Copyright 2015 Google Inc. All Rights Reserved.
  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. package bigquery
  15. import (
  16. "fmt"
  17. "reflect"
  18. "testing"
  19. "time"
  20. bq "google.golang.org/api/bigquery/v2"
  21. )
  22. func TestConvertBasicValues(t *testing.T) {
  23. schema := []*FieldSchema{
  24. {Type: StringFieldType},
  25. {Type: IntegerFieldType},
  26. {Type: FloatFieldType},
  27. {Type: BooleanFieldType},
  28. }
  29. row := &bq.TableRow{
  30. F: []*bq.TableCell{
  31. {V: "a"},
  32. {V: "1"},
  33. {V: "1.2"},
  34. {V: "true"},
  35. },
  36. }
  37. got, err := convertRow(row, schema)
  38. if err != nil {
  39. t.Fatalf("error converting: %v", err)
  40. }
  41. want := []Value{"a", 1, 1.2, true}
  42. if !reflect.DeepEqual(got, want) {
  43. t.Errorf("converting basic values: got:\n%v\nwant:\n%v", got, want)
  44. }
  45. }
  46. func TestConvertTime(t *testing.T) {
  47. schema := []*FieldSchema{
  48. {Type: TimestampFieldType},
  49. }
  50. thyme := time.Date(1970, 1, 1, 10, 0, 0, 10, time.UTC)
  51. row := &bq.TableRow{
  52. F: []*bq.TableCell{
  53. {V: fmt.Sprintf("%.10f", float64(thyme.UnixNano())/1e9)},
  54. },
  55. }
  56. got, err := convertRow(row, schema)
  57. if err != nil {
  58. t.Fatalf("error converting: %v", err)
  59. }
  60. if !got[0].(time.Time).Equal(thyme) {
  61. t.Errorf("converting basic values: got:\n%v\nwant:\n%v", got, thyme)
  62. }
  63. }
  64. func TestConvertNullValues(t *testing.T) {
  65. schema := []*FieldSchema{
  66. {Type: StringFieldType},
  67. }
  68. row := &bq.TableRow{
  69. F: []*bq.TableCell{
  70. {V: nil},
  71. },
  72. }
  73. got, err := convertRow(row, schema)
  74. if err != nil {
  75. t.Fatalf("error converting: %v", err)
  76. }
  77. want := []Value{nil}
  78. if !reflect.DeepEqual(got, want) {
  79. t.Errorf("converting null values: got:\n%v\nwant:\n%v", got, want)
  80. }
  81. }
  82. func TestBasicRepetition(t *testing.T) {
  83. schema := []*FieldSchema{
  84. {Type: IntegerFieldType, Repeated: true},
  85. }
  86. row := &bq.TableRow{
  87. F: []*bq.TableCell{
  88. {
  89. V: []interface{}{
  90. map[string]interface{}{
  91. "v": "1",
  92. },
  93. map[string]interface{}{
  94. "v": "2",
  95. },
  96. map[string]interface{}{
  97. "v": "3",
  98. },
  99. },
  100. },
  101. },
  102. }
  103. got, err := convertRow(row, schema)
  104. if err != nil {
  105. t.Fatalf("error converting: %v", err)
  106. }
  107. want := []Value{[]Value{1, 2, 3}}
  108. if !reflect.DeepEqual(got, want) {
  109. t.Errorf("converting basic repeated values: got:\n%v\nwant:\n%v", got, want)
  110. }
  111. }
  112. func TestNestedRecordContainingRepetition(t *testing.T) {
  113. schema := []*FieldSchema{
  114. {
  115. Type: RecordFieldType,
  116. Schema: Schema{
  117. {Type: IntegerFieldType, Repeated: true},
  118. },
  119. },
  120. }
  121. row := &bq.TableRow{
  122. F: []*bq.TableCell{
  123. {
  124. V: map[string]interface{}{
  125. "f": []interface{}{
  126. map[string]interface{}{
  127. "v": []interface{}{
  128. map[string]interface{}{"v": "1"},
  129. map[string]interface{}{"v": "2"},
  130. map[string]interface{}{"v": "3"},
  131. },
  132. },
  133. },
  134. },
  135. },
  136. },
  137. }
  138. got, err := convertRow(row, schema)
  139. if err != nil {
  140. t.Fatalf("error converting: %v", err)
  141. }
  142. want := []Value{[]Value{[]Value{1, 2, 3}}}
  143. if !reflect.DeepEqual(got, want) {
  144. t.Errorf("converting basic repeated values: got:\n%v\nwant:\n%v", got, want)
  145. }
  146. }
  147. func TestRepeatedRecordContainingRepetition(t *testing.T) {
  148. schema := []*FieldSchema{
  149. {
  150. Type: RecordFieldType,
  151. Repeated: true,
  152. Schema: Schema{
  153. {Type: IntegerFieldType, Repeated: true},
  154. },
  155. },
  156. }
  157. row := &bq.TableRow{F: []*bq.TableCell{
  158. {
  159. V: []interface{}{ // repeated records.
  160. map[string]interface{}{ // first record.
  161. "v": map[string]interface{}{ // pointless single-key-map wrapper.
  162. "f": []interface{}{ // list of record fields.
  163. map[string]interface{}{ // only record (repeated ints)
  164. "v": []interface{}{ // pointless wrapper.
  165. map[string]interface{}{
  166. "v": "1",
  167. },
  168. map[string]interface{}{
  169. "v": "2",
  170. },
  171. map[string]interface{}{
  172. "v": "3",
  173. },
  174. },
  175. },
  176. },
  177. },
  178. },
  179. map[string]interface{}{ // second record.
  180. "v": map[string]interface{}{
  181. "f": []interface{}{
  182. map[string]interface{}{
  183. "v": []interface{}{
  184. map[string]interface{}{
  185. "v": "4",
  186. },
  187. map[string]interface{}{
  188. "v": "5",
  189. },
  190. map[string]interface{}{
  191. "v": "6",
  192. },
  193. },
  194. },
  195. },
  196. },
  197. },
  198. },
  199. },
  200. }}
  201. got, err := convertRow(row, schema)
  202. if err != nil {
  203. t.Fatalf("error converting: %v", err)
  204. }
  205. want := []Value{ // the row is a list of length 1, containing an entry for the repeated record.
  206. []Value{ // the repeated record is a list of length 2, containing an entry for each repetition.
  207. []Value{ // the record is a list of length 1, containing an entry for the repeated integer field.
  208. []Value{1, 2, 3}, // the repeated integer field is a list of length 3.
  209. },
  210. []Value{ // second record
  211. []Value{4, 5, 6},
  212. },
  213. },
  214. }
  215. if !reflect.DeepEqual(got, want) {
  216. t.Errorf("converting repeated records with repeated values: got:\n%v\nwant:\n%v", got, want)
  217. }
  218. }
  219. func TestRepeatedRecordContainingRecord(t *testing.T) {
  220. schema := []*FieldSchema{
  221. {
  222. Type: RecordFieldType,
  223. Repeated: true,
  224. Schema: Schema{
  225. {
  226. Type: StringFieldType,
  227. },
  228. {
  229. Type: RecordFieldType,
  230. Schema: Schema{
  231. {Type: IntegerFieldType},
  232. {Type: StringFieldType},
  233. },
  234. },
  235. },
  236. },
  237. }
  238. row := &bq.TableRow{F: []*bq.TableCell{
  239. {
  240. V: []interface{}{ // repeated records.
  241. map[string]interface{}{ // first record.
  242. "v": map[string]interface{}{ // pointless single-key-map wrapper.
  243. "f": []interface{}{ // list of record fields.
  244. map[string]interface{}{ // first record field (name)
  245. "v": "first repeated record",
  246. },
  247. map[string]interface{}{ // second record field (nested record).
  248. "v": map[string]interface{}{ // pointless single-key-map wrapper.
  249. "f": []interface{}{ // nested record fields
  250. map[string]interface{}{
  251. "v": "1",
  252. },
  253. map[string]interface{}{
  254. "v": "two",
  255. },
  256. },
  257. },
  258. },
  259. },
  260. },
  261. },
  262. map[string]interface{}{ // second record.
  263. "v": map[string]interface{}{
  264. "f": []interface{}{
  265. map[string]interface{}{
  266. "v": "second repeated record",
  267. },
  268. map[string]interface{}{
  269. "v": map[string]interface{}{
  270. "f": []interface{}{
  271. map[string]interface{}{
  272. "v": "3",
  273. },
  274. map[string]interface{}{
  275. "v": "four",
  276. },
  277. },
  278. },
  279. },
  280. },
  281. },
  282. },
  283. },
  284. },
  285. }}
  286. got, err := convertRow(row, schema)
  287. if err != nil {
  288. t.Fatalf("error converting: %v", err)
  289. }
  290. // TODO: test with flattenresults.
  291. want := []Value{ // the row is a list of length 1, containing an entry for the repeated record.
  292. []Value{ // the repeated record is a list of length 2, containing an entry for each repetition.
  293. []Value{ // record contains a string followed by a nested record.
  294. "first repeated record",
  295. []Value{
  296. 1,
  297. "two",
  298. },
  299. },
  300. []Value{ // second record.
  301. "second repeated record",
  302. []Value{
  303. 3,
  304. "four",
  305. },
  306. },
  307. },
  308. }
  309. if !reflect.DeepEqual(got, want) {
  310. t.Errorf("converting repeated records containing record : got:\n%v\nwant:\n%v", got, want)
  311. }
  312. }