| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,7 +66,12 @@ def lint_setup_py(session): | |||
| 66 | 66 | def default(session): | |
| 67 | 67 | # Install all test dependencies, then install this package in-place. | |
| 68 | 68 | session.install( | |
| 69 | - "django~=2.2", "mock", "mock-import", "pytest", "pytest-cov" | ||
| 69 | + "django~=2.2", | ||
| 70 | + "mock", | ||
| 71 | + "mock-import", | ||
| 72 | + "pytest", | ||
| 73 | + "pytest-cov", | ||
| 74 | + "coverage", | ||
| 70 | 75 | ) | |
| 71 | 76 | session.install("-e", ".") | |
| 72 | 77 | ||
@@ -79,7 +84,7 @@ def default(session): | |||
| 79 | 84 | "--cov-append", | |
| 80 | 85 | "--cov-config=.coveragerc", | |
| 81 | 86 | "--cov-report=", | |
| 82 | - "--cov-fail-under=20", | ||
| 87 | + "--cov-fail-under=68", | ||
| 83 | 88 | os.path.join("tests", "unit"), | |
| 84 | 89 | *session.posargs | |
| 85 | 90 | ) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + import os | ||
| 2 | + import django | ||
| 3 | + from django.conf import settings | ||
| 4 | + | ||
| 5 | + # We manually designate which settings we will be using in an environment | ||
| 6 | + # variable. This is similar to what occurs in the `manage.py` file. | ||
| 7 | + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings") | ||
| 8 | + | ||
| 9 | + | ||
| 10 | + # `pytest` automatically calls this function once when tests are run. | ||
| 11 | + def pytest_configure(): | ||
| 12 | + settings.DEBUG = False | ||
| 13 | + django.setup() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + # Copyright 2021 Google LLC | ||
| 2 | + # | ||
| 3 | + # Use of this source code is governed by a BSD-style | ||
| 4 | + # license that can be found in the LICENSE file or at | ||
| 5 | + # https://developers.google.com/open-source/licenses/bsd | ||
| 6 | + | ||
| 7 | + DEBUG = True | ||
| 8 | + USE_TZ = True | ||
| 9 | + | ||
| 10 | + INSTALLED_APPS = [ | ||
| 11 | + "django_spanner", # Must be the first entry | ||
| 12 | + "django.contrib.contenttypes", | ||
| 13 | + "django.contrib.auth", | ||
| 14 | + "django.contrib.sites", | ||
| 15 | + "django.contrib.sessions", | ||
| 16 | + "django.contrib.messages", | ||
| 17 | + "django.contrib.staticfiles", | ||
| 18 | + "tests", | ||
| 19 | + ] | ||
| 20 | + | ||
| 21 | + TIME_ZONE = "UTC" | ||
| 22 | + | ||
| 23 | + DATABASES = { | ||
| 24 | + "default": { | ||
| 25 | + "ENGINE": "django_spanner", | ||
| 26 | + "PROJECT": "emulator-local", | ||
| 27 | + "INSTANCE": "django-test-instance", | ||
| 28 | + "NAME": "django-test-db", | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + SECRET_KEY = "spanner emulator secret key" | ||
| 32 | + | ||
| 33 | + PASSWORD_HASHERS = [ | ||
| 34 | + "django.contrib.auth.hashers.MD5PasswordHasher", | ||
| 35 | + ] | ||
| 36 | + | ||
| 37 | + SITE_ID = 1 | ||
| 38 | + | ||
| 39 | + CONN_MAX_AGE = 60 | ||
| 40 | + | ||
| 41 | + ENGINE = "django_spanner" | ||
| 42 | + PROJECT = "emulator-local" | ||
| 43 | + INSTANCE = "django-test-instance" | ||
| 44 | + NAME = "django-test-db" | ||
| 45 | + OPTIONS = {} | ||
| 46 | + AUTOCOMMIT = True | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,61 @@ | |||
| 1 | + # Copyright 2021 Google LLC | ||
| 2 | + # | ||
| 3 | + # Use of this source code is governed by a BSD-style | ||
| 4 | + # license that can be found in the LICENSE file or at | ||
| 5 | + # https://developers.google.com/open-source/licenses/bsd | ||
| 6 | + """ | ||
| 7 | + Different models used for testing django-spanner code. | ||
| 8 | + """ | ||
| 9 | + from django.db import models | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + # Register transformations for model fields. | ||
| 13 | + class UpperCase(models.Transform): | ||
| 14 | + lookup_name = "upper" | ||
| 15 | + function = "UPPER" | ||
| 16 | + bilateral = True | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + models.CharField.register_lookup(UpperCase) | ||
| 20 | + models.TextField.register_lookup(UpperCase) | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + # Models | ||
| 24 | + class ModelDecimalField(models.Model): | ||
| 25 | + field = models.DecimalField() | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + class ModelCharField(models.Model): | ||
| 29 | + field = models.CharField() | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + class Item(models.Model): | ||
| 33 | + item_id = models.IntegerField() | ||
| 34 | + name = models.CharField(max_length=10) | ||
| 35 | + created = models.DateTimeField() | ||
| 36 | + modified = models.DateTimeField(blank=True, null=True) | ||
| 37 | + | ||
| 38 | + class Meta: | ||
| 39 | + ordering = ["name"] | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + class Number(models.Model): | ||
| 43 | + num = models.IntegerField() | ||
| 44 | + decimal_num = models.DecimalField(max_digits=5, decimal_places=2) | ||
| 45 | + item = models.ForeignKey(Item, models.CASCADE) | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + class Author(models.Model): | ||
| 49 | + name = models.CharField(max_length=40) | ||
| 50 | + last_name = models.CharField(max_length=40) | ||
| 51 | + num = models.IntegerField(unique=True) | ||
| 52 | + created = models.DateTimeField() | ||
| 53 | + modified = models.DateTimeField(blank=True, null=True) | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + class Report(models.Model): | ||
| 57 | + name = models.CharField(max_length=10) | ||
| 58 | + creator = models.ForeignKey(Author, models.CASCADE, null=True) | ||
| 59 | + | ||
| 60 | + class Meta: | ||
| 61 | + ordering = ["name"] | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,33 @@ | |||
| 1 | + # Copyright 2021 Google LLC | ||
| 2 | + # | ||
| 3 | + # Use of this source code is governed by a BSD-style | ||
| 4 | + # license that can be found in the LICENSE file or at | ||
| 5 | + # https://developers.google.com/open-source/licenses/bsd | ||
| 6 | + | ||
| 7 | + from django_spanner.client import DatabaseClient | ||
| 8 | + from django_spanner.base import DatabaseWrapper | ||
| 9 | + from django_spanner.operations import DatabaseOperations | ||
| 10 | + from unittest import TestCase | ||
| 11 | + import os | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + class SpannerSimpleTestClass(TestCase): | ||
| 15 | + @classmethod | ||
| 16 | + def setUpClass(cls): | ||
| 17 | + cls.PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] | ||
| 18 | + | ||
| 19 | + cls.INSTANCE_ID = "instance_id" | ||
| 20 | + cls.DATABASE_ID = "database_id" | ||
| 21 | + cls.USER_AGENT = "django_spanner/2.2.0a1" | ||
| 22 | + cls.OPTIONS = {"option": "dummy"} | ||
| 23 | + | ||
| 24 | + cls.settings_dict = { | ||
| 25 | + "PROJECT": cls.PROJECT, | ||
| 26 | + "INSTANCE": cls.INSTANCE_ID, | ||
| 27 | + "NAME": cls.DATABASE_ID, | ||
| 28 | + "user_agent": cls.USER_AGENT, | ||
| 29 | + "OPTIONS": cls.OPTIONS, | ||
| 30 | + } | ||
| 31 | + cls.db_client = DatabaseClient(cls.settings_dict) | ||
| 32 | + cls.db_wrapper = cls.connection = DatabaseWrapper(cls.settings_dict) | ||
| 33 | + cls.db_operations = DatabaseOperations(cls.connection) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,59 +4,24 @@ | |||
| 4 | 4 | # license that can be found in the LICENSE file or at | |
| 5 | 5 | # https://developers.google.com/open-source/licenses/bsd | |
| 6 | 6 | ||
| 7 | - import sys | ||
| 8 | - import unittest | ||
| 9 | - import os | ||
| 10 | - | ||
| 11 | - from mock_import import mock_import | ||
| 12 | 7 | from unittest import mock | |
| 8 | + from tests.unit.django_spanner.simple_test import SpannerSimpleTestClass | ||
| 13 | 9 | ||
| 14 | 10 | ||
| 15 | - @mock_import() | ||
| 16 | - @unittest.skipIf( | ||
| 17 | - sys.version_info < (3, 6), reason="Skipping Python versions <= 3.5" | ||
| 18 | - ) | ||
| 19 | - class TestBase(unittest.TestCase): | ||
| 20 | - PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] | ||
| 21 | - INSTANCE_ID = "instance_id" | ||
| 22 | - DATABASE_ID = "database_id" | ||
| 23 | - USER_AGENT = "django_spanner/2.2.0a1" | ||
| 24 | - OPTIONS = {"option": "dummy"} | ||
| 25 | - | ||
| 26 | - settings_dict = { | ||
| 27 | - "PROJECT": PROJECT, | ||
| 28 | - "INSTANCE": INSTANCE_ID, | ||
| 29 | - "NAME": DATABASE_ID, | ||
| 30 | - "user_agent": USER_AGENT, | ||
| 31 | - "OPTIONS": OPTIONS, | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - def _get_target_class(self): | ||
| 35 | - from django_spanner.base import DatabaseWrapper | ||
| 36 | - | ||
| 37 | - return DatabaseWrapper | ||
| 38 | - | ||
| 39 | - def _make_one(self, *args, **kwargs): | ||
| 40 | - return self._get_target_class()(*args, **kwargs) | ||
| 41 | - | ||
| 11 | + class TestBase(SpannerSimpleTestClass): | ||
| 42 | 12 | def test_property_instance(self): | |
| 43 | - settings_dict = {"INSTANCE": "instance"} | ||
| 44 | - db_wrapper = self._make_one(settings_dict=settings_dict) | ||
| 45 | - | ||
| 46 | 13 | with mock.patch("django_spanner.base.spanner") as mock_spanner: | |
| 47 | 14 | mock_spanner.Client = mock_client = mock.MagicMock() | |
| 48 | 15 | mock_client().instance = mock_instance = mock.MagicMock() | |
| 49 | - _ = db_wrapper.instance | ||
| 50 | - mock_instance.assert_called_once_with(settings_dict["INSTANCE"]) | ||
| 16 | + _ = self.db_wrapper.instance | ||
| 17 | + mock_instance.assert_called_once_with(self.INSTANCE_ID) | ||
| 51 | 18 | ||
| 52 | - def test_property__nodb_connection(self): | ||
| 53 | - db_wrapper = self._make_one(None) | ||
| 19 | + def test_property_nodb_connection(self): | ||
| 54 | 20 | with self.assertRaises(NotImplementedError): | |
| 55 | - db_wrapper._nodb_connection() | ||
| 21 | + self.db_wrapper._nodb_connection() | ||
| 56 | 22 | ||
| 57 | 23 | def test_get_connection_params(self): | |
| 58 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 59 | - params = db_wrapper.get_connection_params() | ||
| 24 | + params = self.db_wrapper.get_connection_params() | ||
| 60 | 25 | ||
| 61 | 26 | self.assertEqual(params["project"], self.PROJECT) | |
| 62 | 27 | self.assertEqual(params["instance_id"], self.INSTANCE_ID) | |
@@ -65,54 +30,50 @@ def test_get_connection_params(self): | |||
| 65 | 30 | self.assertEqual(params["option"], self.OPTIONS["option"]) | |
| 66 | 31 | ||
| 67 | 32 | def test_get_new_connection(self): | |
| 68 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 69 | - db_wrapper.Database = mock_database = mock.MagicMock() | ||
| 33 | + self.db_wrapper.Database = mock_database = mock.MagicMock() | ||
| 70 | 34 | mock_database.connect = mock_connection = mock.MagicMock() | |
| 71 | 35 | conn_params = {"test_param": "dummy"} | |
| 72 | - db_wrapper.get_new_connection(conn_params) | ||
| 36 | + self.db_wrapper.get_new_connection(conn_params) | ||
| 73 | 37 | mock_connection.assert_called_once_with(**conn_params) | |
| 74 | 38 | ||
| 75 | 39 | def test_init_connection_state(self): | |
| 76 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 77 | - db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 40 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 78 | 41 | mock_connection.close = mock_close = mock.MagicMock() | |
| 79 | - db_wrapper.init_connection_state() | ||
| 42 | + self.db_wrapper.init_connection_state() | ||
| 80 | 43 | mock_close.assert_called_once_with() | |
| 81 | 44 | ||
| 82 | 45 | def test_create_cursor(self): | |
| 83 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 84 | - db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 46 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 85 | 47 | mock_connection.cursor = mock_cursor = mock.MagicMock() | |
| 86 | - db_wrapper.create_cursor() | ||
| 48 | + self.db_wrapper.create_cursor() | ||
| 87 | 49 | mock_cursor.assert_called_once_with() | |
| 88 | 50 | ||
| 89 | - def test__set_autocommit(self): | ||
| 90 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 91 | - db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 51 | + def test_set_autocommit(self): | ||
| 52 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 92 | 53 | mock_connection.autocommit = False | |
| 93 | - db_wrapper._set_autocommit(True) | ||
| 54 | + self.db_wrapper._set_autocommit(True) | ||
| 94 | 55 | self.assertEqual(mock_connection.autocommit, True) | |
| 95 | 56 | ||
| 96 | 57 | def test_is_usable(self): | |
| 97 | - from google.cloud.spanner_dbapi.exceptions import Error | ||
| 98 | - | ||
| 99 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 100 | - db_wrapper.connection = None | ||
| 101 | - self.assertFalse(db_wrapper.is_usable()) | ||
| 58 | + self.db_wrapper.connection = None | ||
| 59 | + self.assertFalse(self.db_wrapper.is_usable()) | ||
| 102 | 60 | ||
| 103 | - db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 61 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 104 | 62 | mock_connection.is_closed = True | |
| 105 | - self.assertFalse(db_wrapper.is_usable()) | ||
| 63 | + self.assertFalse(self.db_wrapper.is_usable()) | ||
| 106 | 64 | ||
| 107 | 65 | mock_connection.is_closed = False | |
| 108 | - self.assertTrue(db_wrapper.is_usable()) | ||
| 66 | + self.assertTrue(self.db_wrapper.is_usable()) | ||
| 67 | + | ||
| 68 | + def test_is_usable_with_error(self): | ||
| 69 | + from google.cloud.spanner_dbapi.exceptions import Error | ||
| 109 | 70 | ||
| 71 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 110 | 72 | mock_connection.cursor = mock.MagicMock(side_effect=Error) | |
| 111 | - self.assertFalse(db_wrapper.is_usable()) | ||
| 73 | + self.assertFalse(self.db_wrapper.is_usable()) | ||
| 112 | 74 | ||
| 113 | - def test__start_transaction_under_autocommit(self): | ||
| 114 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 115 | - db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 75 | + def test_start_transaction_under_autocommit(self): | ||
| 76 | + self.db_wrapper.connection = mock_connection = mock.MagicMock() | ||
| 116 | 77 | mock_connection.cursor = mock_cursor = mock.MagicMock() | |
| 117 | - db_wrapper._start_transaction_under_autocommit() | ||
| 78 | + self.db_wrapper._start_transaction_under_autocommit() | ||
| 118 | 79 | mock_cursor.assert_called_once_with() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,41 +4,12 @@ | |||
| 4 | 4 | # license that can be found in the LICENSE file or at | |
| 5 | 5 | # https://developers.google.com/open-source/licenses/bsd | |
| 6 | 6 | ||
| 7 | - import sys | ||
| 8 | - import unittest | ||
| 9 | - import os | ||
| 10 | 7 | ||
| 8 | + from google.cloud.spanner_dbapi.exceptions import NotSupportedError | ||
| 9 | + from tests.unit.django_spanner.simple_test import SpannerSimpleTestClass | ||
| 11 | 10 | ||
| 12 | - @unittest.skipIf( | ||
| 13 | - sys.version_info < (3, 6), reason="Skipping Python versions <= 3.5" | ||
| 14 | - ) | ||
| 15 | - class TestClient(unittest.TestCase): | ||
| 16 | - PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"] | ||
| 17 | - INSTANCE_ID = "instance_id" | ||
| 18 | - DATABASE_ID = "database_id" | ||
| 19 | - USER_AGENT = "django_spanner/2.2.0a1" | ||
| 20 | - OPTIONS = {"option": "dummy"} | ||
| 21 | - | ||
| 22 | - settings_dict = { | ||
| 23 | - "PROJECT": PROJECT, | ||
| 24 | - "INSTANCE": INSTANCE_ID, | ||
| 25 | - "NAME": DATABASE_ID, | ||
| 26 | - "user_agent": USER_AGENT, | ||
| 27 | - "OPTIONS": OPTIONS, | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - def _get_target_class(self): | ||
| 31 | - from django_spanner.client import DatabaseClient | ||
| 32 | - | ||
| 33 | - return DatabaseClient | ||
| 34 | - | ||
| 35 | - def _make_one(self, *args, **kwargs): | ||
| 36 | - return self._get_target_class()(*args, **kwargs) | ||
| 37 | 11 | ||
| 12 | + class TestClient(SpannerSimpleTestClass): | ||
| 38 | 13 | def test_runshell(self): | |
| 39 | - from google.cloud.spanner_dbapi.exceptions import NotSupportedError | ||
| 40 | - | ||
| 41 | - db_wrapper = self._make_one(self.settings_dict) | ||
| 42 | - | ||
| 43 | 14 | with self.assertRaises(NotSupportedError): | |
| 44 | - db_wrapper.runshell(parameters=self.settings_dict) | ||
| 15 | + self.db_client.runshell(parameters=self.settings_dict) | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments