|
1 | 1 | # -*- coding: utf-8 -*-
|
2 | 2 |
|
3 | 3 | import os
|
4 |
| -import re |
5 | 4 | import sys
|
6 | 5 | from datetime import datetime
|
7 | 6 | from random import randint
|
|
13 | 12 | import pytz
|
14 | 13 | from pandas import DataFrame, NaT, compat
|
15 | 14 | from pandas.compat import range, u
|
16 |
| -from pandas.compat.numpy import np_datetime64_compat |
17 | 15 |
|
18 | 16 | from pandas_gbq import gbq
|
19 | 17 |
|
20 | 18 | try:
|
21 | 19 | import mock
|
22 |
| -except ImportError: |
| 20 | +except ImportError: # pragma: NO COVER |
23 | 21 | from unittest import mock
|
24 | 22 |
|
25 | 23 | TABLE_ID = 'new_test'
|
@@ -280,233 +278,7 @@ def test_get_user_account_credentials_returns_credentials(self):
|
280 | 278 | assert isinstance(credentials, Credentials)
|
281 | 279 |
|
282 | 280 |
|
283 |
| -class TestGBQUnit(object): |
284 |
| - |
285 |
| - @pytest.fixture(autouse=True) |
286 |
| - def mock_bigquery_client(self, monkeypatch): |
287 |
| - import google.cloud.bigquery |
288 |
| - import google.cloud.bigquery.table |
289 |
| - mock_client = mock.create_autospec(google.cloud.bigquery.Client) |
290 |
| - # Mock out SELECT 1 query results. |
291 |
| - mock_query = mock.create_autospec(google.cloud.bigquery.QueryJob) |
292 |
| - mock_query.state = 'DONE' |
293 |
| - mock_rows = mock.create_autospec( |
294 |
| - google.cloud.bigquery.table.RowIterator) |
295 |
| - mock_rows.total_rows = 1 |
296 |
| - mock_rows.schema = [ |
297 |
| - google.cloud.bigquery.SchemaField('_f0', 'INTEGER')] |
298 |
| - mock_rows.__iter__.return_value = [(1,)] |
299 |
| - mock_query.result.return_value = mock_rows |
300 |
| - mock_client.query.return_value = mock_query |
301 |
| - monkeypatch.setattr( |
302 |
| - gbq.GbqConnector, 'get_client', lambda _: mock_client) |
303 |
| - |
304 |
| - @pytest.fixture(autouse=True) |
305 |
| - def no_auth(self, monkeypatch): |
306 |
| - import google.auth.credentials |
307 |
| - mock_credentials = mock.create_autospec( |
308 |
| - google.auth.credentials.Credentials) |
309 |
| - monkeypatch.setattr( |
310 |
| - gbq.GbqConnector, |
311 |
| - 'get_application_default_credentials', |
312 |
| - lambda _: mock_credentials) |
313 |
| - monkeypatch.setattr( |
314 |
| - gbq.GbqConnector, |
315 |
| - 'get_user_account_credentials', |
316 |
| - lambda _: mock_credentials) |
317 |
| - |
318 |
| - def test_should_return_credentials_path_set_by_env_var(self): |
319 |
| - env = {'PANDAS_GBQ_CREDENTIALS_FILE': '/tmp/dummy.dat'} |
320 |
| - with mock.patch.dict('os.environ', env): |
321 |
| - assert gbq._get_credentials_file() == '/tmp/dummy.dat' |
322 |
| - |
323 |
| - @pytest.mark.parametrize( |
324 |
| - ('input', 'type_', 'expected'), [ |
325 |
| - (1, 'INTEGER', int(1)), |
326 |
| - (1, 'FLOAT', float(1)), |
327 |
| - pytest.param('false', 'BOOLEAN', False, marks=pytest.mark.xfail), |
328 |
| - pytest.param( |
329 |
| - '0e9', 'TIMESTAMP', |
330 |
| - np_datetime64_compat('1970-01-01T00:00:00Z'), |
331 |
| - marks=pytest.mark.xfail), |
332 |
| - ('STRING', 'STRING', 'STRING'), |
333 |
| - ]) |
334 |
| - def test_should_return_bigquery_correctly_typed( |
335 |
| - self, input, type_, expected): |
336 |
| - result = gbq._parse_data( |
337 |
| - dict(fields=[dict(name='x', type=type_, mode='NULLABLE')]), |
338 |
| - rows=[[input]]).iloc[0, 0] |
339 |
| - assert result == expected |
340 |
| - |
341 |
| - def test_to_gbq_should_fail_if_invalid_table_name_passed(self): |
342 |
| - with pytest.raises(gbq.NotFoundException): |
343 |
| - gbq.to_gbq(DataFrame(), 'invalid_table_name', project_id="1234") |
344 |
| - |
345 |
| - def test_to_gbq_with_no_project_id_given_should_fail(self): |
346 |
| - with pytest.raises(TypeError): |
347 |
| - gbq.to_gbq(DataFrame(), 'dataset.tablename') |
348 |
| - |
349 |
| - def test_to_gbq_with_verbose_new_pandas_warns_deprecation(self): |
350 |
| - import pkg_resources |
351 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
352 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
353 |
| - with pytest.warns(FutureWarning), \ |
354 |
| - mock.patch( |
355 |
| - 'pkg_resources.Distribution.parsed_version', |
356 |
| - new_callable=mock.PropertyMock) as mock_version: |
357 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
358 |
| - try: |
359 |
| - gbq.to_gbq( |
360 |
| - DataFrame(), |
361 |
| - 'dataset.tablename', |
362 |
| - project_id='my-project', |
363 |
| - verbose=True) |
364 |
| - except gbq.TableCreationError: |
365 |
| - pass |
366 |
| - |
367 |
| - def test_to_gbq_with_not_verbose_new_pandas_warns_deprecation(self): |
368 |
| - import pkg_resources |
369 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
370 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
371 |
| - with pytest.warns(FutureWarning), \ |
372 |
| - mock.patch( |
373 |
| - 'pkg_resources.Distribution.parsed_version', |
374 |
| - new_callable=mock.PropertyMock) as mock_version: |
375 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
376 |
| - try: |
377 |
| - gbq.to_gbq( |
378 |
| - DataFrame(), |
379 |
| - 'dataset.tablename', |
380 |
| - project_id='my-project', |
381 |
| - verbose=False) |
382 |
| - except gbq.TableCreationError: |
383 |
| - pass |
384 |
| - |
385 |
| - def test_to_gbq_wo_verbose_w_new_pandas_no_warnings(self, recwarn): |
386 |
| - import pkg_resources |
387 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
388 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
389 |
| - with mock.patch( |
390 |
| - 'pkg_resources.Distribution.parsed_version', |
391 |
| - new_callable=mock.PropertyMock) as mock_version: |
392 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
393 |
| - try: |
394 |
| - gbq.to_gbq( |
395 |
| - DataFrame(), 'dataset.tablename', project_id='my-project') |
396 |
| - except gbq.TableCreationError: |
397 |
| - pass |
398 |
| - assert len(recwarn) == 0 |
399 |
| - |
400 |
| - def test_to_gbq_with_verbose_old_pandas_no_warnings(self, recwarn): |
401 |
| - import pkg_resources |
402 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
403 |
| - pandas_version = pkg_resources.parse_version('0.22.0') |
404 |
| - with mock.patch( |
405 |
| - 'pkg_resources.Distribution.parsed_version', |
406 |
| - new_callable=mock.PropertyMock) as mock_version: |
407 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
408 |
| - try: |
409 |
| - gbq.to_gbq( |
410 |
| - DataFrame(), |
411 |
| - 'dataset.tablename', |
412 |
| - project_id='my-project', |
413 |
| - verbose=True) |
414 |
| - except gbq.TableCreationError: |
415 |
| - pass |
416 |
| - assert len(recwarn) == 0 |
417 |
| - |
418 |
| - def test_read_gbq_with_no_project_id_given_should_fail(self): |
419 |
| - with pytest.raises(TypeError): |
420 |
| - gbq.read_gbq('SELECT 1') |
421 |
| - |
422 |
| - def test_that_parse_data_works_properly(self): |
423 |
| - |
424 |
| - from google.cloud.bigquery.table import Row |
425 |
| - test_schema = {'fields': [ |
426 |
| - {'mode': 'NULLABLE', 'name': 'column_x', 'type': 'STRING'}]} |
427 |
| - field_to_index = {'column_x': 0} |
428 |
| - values = ('row_value',) |
429 |
| - test_page = [Row(values, field_to_index)] |
430 |
| - |
431 |
| - test_output = gbq._parse_data(test_schema, test_page) |
432 |
| - correct_output = DataFrame({'column_x': ['row_value']}) |
433 |
| - tm.assert_frame_equal(test_output, correct_output) |
434 |
| - |
435 |
| - def test_read_gbq_with_invalid_private_key_json_should_fail(self): |
436 |
| - with pytest.raises(gbq.InvalidPrivateKeyFormat): |
437 |
| - gbq.read_gbq('SELECT 1', project_id='x', private_key='y') |
438 |
| - |
439 |
| - def test_read_gbq_with_empty_private_key_json_should_fail(self): |
440 |
| - with pytest.raises(gbq.InvalidPrivateKeyFormat): |
441 |
| - gbq.read_gbq('SELECT 1', project_id='x', private_key='{}') |
442 |
| - |
443 |
| - def test_read_gbq_with_private_key_json_wrong_types_should_fail(self): |
444 |
| - with pytest.raises(gbq.InvalidPrivateKeyFormat): |
445 |
| - gbq.read_gbq( |
446 |
| - 'SELECT 1', project_id='x', |
447 |
| - private_key='{ "client_email" : 1, "private_key" : True }') |
448 |
| - |
449 |
| - def test_read_gbq_with_empty_private_key_file_should_fail(self): |
450 |
| - with tm.ensure_clean() as empty_file_path: |
451 |
| - with pytest.raises(gbq.InvalidPrivateKeyFormat): |
452 |
| - gbq.read_gbq('SELECT 1', project_id='x', |
453 |
| - private_key=empty_file_path) |
454 |
| - |
455 |
| - def test_read_gbq_with_corrupted_private_key_json_should_fail(self): |
456 |
| - _skip_if_no_private_key_contents() |
457 |
| - |
458 |
| - with pytest.raises(gbq.InvalidPrivateKeyFormat): |
459 |
| - gbq.read_gbq( |
460 |
| - 'SELECT 1', project_id='x', |
461 |
| - private_key=re.sub('[a-z]', '9', _get_private_key_contents())) |
462 |
| - |
463 |
| - def test_read_gbq_with_verbose_new_pandas_warns_deprecation(self): |
464 |
| - import pkg_resources |
465 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
466 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
467 |
| - with pytest.warns(FutureWarning), \ |
468 |
| - mock.patch( |
469 |
| - 'pkg_resources.Distribution.parsed_version', |
470 |
| - new_callable=mock.PropertyMock) as mock_version: |
471 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
472 |
| - gbq.read_gbq('SELECT 1', project_id='my-project', verbose=True) |
473 |
| - |
474 |
| - def test_read_gbq_with_not_verbose_new_pandas_warns_deprecation(self): |
475 |
| - import pkg_resources |
476 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
477 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
478 |
| - with pytest.warns(FutureWarning), \ |
479 |
| - mock.patch( |
480 |
| - 'pkg_resources.Distribution.parsed_version', |
481 |
| - new_callable=mock.PropertyMock) as mock_version: |
482 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
483 |
| - gbq.read_gbq('SELECT 1', project_id='my-project', verbose=False) |
484 |
| - |
485 |
| - def test_read_gbq_wo_verbose_w_new_pandas_no_warnings(self, recwarn): |
486 |
| - import pkg_resources |
487 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
488 |
| - pandas_version = pkg_resources.parse_version('0.23.0') |
489 |
| - with mock.patch( |
490 |
| - 'pkg_resources.Distribution.parsed_version', |
491 |
| - new_callable=mock.PropertyMock) as mock_version: |
492 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
493 |
| - gbq.read_gbq('SELECT 1', project_id='my-project') |
494 |
| - assert len(recwarn) == 0 |
495 |
| - |
496 |
| - def test_read_gbq_with_verbose_old_pandas_no_warnings(self, recwarn): |
497 |
| - import pkg_resources |
498 |
| - min_bq_version = pkg_resources.parse_version('0.29.0') |
499 |
| - pandas_version = pkg_resources.parse_version('0.22.0') |
500 |
| - with mock.patch( |
501 |
| - 'pkg_resources.Distribution.parsed_version', |
502 |
| - new_callable=mock.PropertyMock) as mock_version: |
503 |
| - mock_version.side_effect = [min_bq_version, pandas_version] |
504 |
| - gbq.read_gbq('SELECT 1', project_id='my-project', verbose=True) |
505 |
| - assert len(recwarn) == 0 |
506 |
| - |
507 |
| - |
508 | 281 | def test_should_read(project, credentials):
|
509 |
| - |
510 | 282 | query = 'SELECT "PI" AS valid_string'
|
511 | 283 | df = gbq.read_gbq(query, project_id=project, private_key=credentials)
|
512 | 284 | tm.assert_frame_equal(df, DataFrame({'valid_string': ['PI']}))
|
|
0 commit comments