Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ad001a8

Browse filesBrowse files
committed
feat: updated nox file for docs and docfx and added unit tests for client
1 parent 6f86877 commit ad001a8
Copy full SHA for ad001a8

File tree

Expand file treeCollapse file tree

9 files changed

+156
-36
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+156
-36
lines changed

‎.gitignore

Copy file name to clipboardExpand all lines: .gitignore
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ bin
1212
MANIFEST
1313
django_tests
1414
__pycache__
15-
15+
# The directory into which Django has been cloned to run the test suite.
16+
django_tests_dir
1617
# Unit test / coverage reports
1718
.coverage
1819
.nox

‎django_spanner/functions.py

Copy file name to clipboardExpand all lines: django_spanner/functions.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
class IfNull(Func):
3030
"""Represent SQL `IFNULL` function."""
31+
3132
function = "IFNULL"
3233
arity = 2
3334

‎django_spanner/introspection.py

Copy file name to clipboardExpand all lines: django_spanner/introspection.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
class DatabaseIntrospection(BaseDatabaseIntrospection):
1717
"""A Spanner-specific version of Django introspection utilities."""
18+
1819
data_types_reverse = {
1920
TypeCode.BOOL: "BooleanField",
2021
TypeCode.BYTES: "BinaryField",

‎django_spanner/operations.py

Copy file name to clipboardExpand all lines: django_spanner/operations.py
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
class DatabaseOperations(BaseDatabaseOperations):
2727
"""A Spanner-specific version of Django database operations."""
28+
2829
cast_data_types = {"CharField": "STRING", "TextField": "STRING"}
2930
cast_char_field_without_max_length = "STRING"
3031
compiler_module = "django_spanner.compiler"
@@ -108,7 +109,9 @@ def bulk_insert_sql(self, fields, placeholder_rows):
108109
values_sql = ", ".join("(%s)" % sql for sql in placeholder_rows_sql)
109110
return "VALUES " + values_sql
110111

111-
def sql_flush(self, style, tables, reset_sequences=False, allow_cascade=False):
112+
def sql_flush(
113+
self, style, tables, reset_sequences=False, allow_cascade=False
114+
):
112115
"""
113116
Override the base class method. Returns a list of SQL statements
114117
required to remove all data from the given database tables (without

‎django_spanner/schema.py

Copy file name to clipboardExpand all lines: django_spanner/schema.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
1313
The database abstraction layer that turns things like “create a model” or
1414
“delete a field” into SQL.
1515
"""
16+
1617
sql_create_table = (
1718
"CREATE TABLE %(table)s (%(definition)s) PRIMARY KEY(%(primary_key)s)"
1819
)

‎docs/conf.py

Copy file name to clipboardExpand all lines: docs/conf.py
+21-22Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818

1919
import sys
2020
import os
21-
22-
from version import __version__
21+
import shlex
2322

2423
# If extensions (or modules to document with autodoc) are in another directory,
2524
# add this directory to sys.path here. If the directory is relative to the
@@ -30,10 +29,12 @@
3029
# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85
3130
sys.path.insert(0, os.path.abspath("."))
3231

32+
__version__ = ""
33+
3334
# -- General configuration ------------------------------------------------
3435

3536
# If your documentation needs a minimal Sphinx version, state it here.
36-
needs_sphinx = "1.6.3"
37+
needs_sphinx = "1.5.5"
3738

3839
# Add any Sphinx extension module names here, as strings. They can be
3940
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -43,6 +44,7 @@
4344
"sphinx.ext.autosummary",
4445
"sphinx.ext.intersphinx",
4546
"sphinx.ext.coverage",
47+
"sphinx.ext.doctest",
4648
"sphinx.ext.napoleon",
4749
"sphinx.ext.todo",
4850
"sphinx.ext.viewcode",
@@ -100,9 +102,6 @@
100102
# directories to ignore when looking for source files.
101103
exclude_patterns = [
102104
"_build",
103-
"samples/AUTHORING_GUIDE.md",
104-
"samples/CONTRIBUTING.md",
105-
"samples/snippets/README.rst",
106105
]
107106

108107
# The reST default role (used for this markup: `text`) to use for all
@@ -258,28 +257,28 @@
258257
# -- Options for LaTeX output ---------------------------------------------
259258

260259
latex_elements = {
261-
# # The paper size ('letterpaper' or 'a4paper').
260+
# The paper size ('letterpaper' or 'a4paper').
262261
# 'papersize': 'letterpaper',
263-
# # The font size ('10pt', '11pt' or '12pt').
262+
# The font size ('10pt', '11pt' or '12pt').
264263
# 'pointsize': '10pt',
265-
# # Additional stuff for the LaTeX preamble.
264+
# Additional stuff for the LaTeX preamble.
266265
# 'preamble': '',
267-
# # Latex figure (float) alignment
266+
# Latex figure (float) alignment
268267
# 'figure_align': 'htbp',
269268
}
270269

271270
# Grouping the document tree into LaTeX files. List of tuples
272271
# (source_start_file, target_name, title, author,
273272
# documentclass ["howto", "manual", or "own class"]). E.g.,
274-
# latex_documents = [
275-
# (
276-
# master_doc,
277-
# "django-google-spanner.tex",
278-
# u"Spanner Django Documentation",
279-
# author,
280-
# "manual",
281-
# )
282-
# ]
273+
latex_documents = [
274+
(
275+
master_doc,
276+
"django-google-spanner.tex",
277+
u"Spanner Django Documentation",
278+
author,
279+
"manual",
280+
)
281+
]
283282

284283
# The name of an image file (relative to this directory)
285284
# to place at the top of the title page.
@@ -352,13 +351,13 @@
352351

353352
# Example configuration for intersphinx: refer to the Python standard library.
354353
intersphinx_mapping = {
355-
"python": ("http://python.readthedocs.org/en/latest/", None),
356-
"google-auth": ("https://google-auth.readthedocs.io/en/stable", None),
354+
"python": ("https://python.readthedocs.org/en/latest/", None),
355+
"google-auth": ("https://googleapis.dev/python/google-auth/latest/", None),
357356
"google.api_core": (
358357
"https://googleapis.dev/python/google-api-core/latest/",
359358
None,
360359
),
361-
"grpc": ("https://grpc.io/grpc/python/", None),
360+
"grpc": ("https://grpc.github.io/grpc/python/", None),
362361
}
363362

364363

‎noxfile.py

Copy file name to clipboardExpand all lines: noxfile.py
+68-8Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717
BLACK_VERSION = "black==19.10b0"
1818
BLACK_PATHS = [
1919
"docs",
20+
"django_spanner",
2021
"tests",
2122
"noxfile.py",
2223
"setup.py",
2324
]
2425

26+
DEFAULT_PYTHON_VERSION = "3.8"
27+
SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"]
28+
UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"]
2529

26-
@nox.session(python="3.8")
30+
31+
@nox.session(python=DEFAULT_PYTHON_VERSION)
2732
def lint(session):
2833
"""Run linters.
2934
@@ -35,7 +40,7 @@ def lint(session):
3540
session.run("flake8", "django_spanner", "tests")
3641

3742

38-
@nox.session(python="3.8")
43+
@nox.session(python="3.6")
3944
def blacken(session):
4045
"""Run black.
4146
@@ -49,7 +54,7 @@ def blacken(session):
4954
session.run("black", *BLACK_PATHS)
5055

5156

52-
@nox.session(python="3.8")
57+
@nox.session(python=DEFAULT_PYTHON_VERSION)
5358
def lint_setup_py(session):
5459
"""Verify that setup.py is valid (including RST check)."""
5560
session.install("docutils", "pygments")
@@ -70,23 +75,41 @@ def default(session):
7075
"py.test",
7176
"--quiet",
7277
"--cov=django_spanner",
73-
"--cov=google.cloud",
7478
"--cov=tests.unit",
7579
"--cov-append",
7680
"--cov-config=.coveragerc",
7781
"--cov-report=",
78-
"--cov-fail-under=60",
82+
"--cov-fail-under=20",
7983
os.path.join("tests", "unit"),
8084
*session.posargs
8185
)
8286

8387

84-
@nox.session(python="3.8")
88+
@nox.session(python=UNIT_TEST_PYTHON_VERSIONS)
89+
def unit(session):
90+
"""Run the unit test suite."""
91+
default(session)
92+
93+
94+
@nox.session(python=DEFAULT_PYTHON_VERSION)
95+
def cover(session):
96+
"""Run the final coverage report.
97+
98+
This outputs the coverage report aggregating coverage from the unit
99+
test runs (not system test runs), and then erases coverage data.
100+
"""
101+
session.install("coverage", "pytest-cov")
102+
session.run("coverage", "report", "--show-missing", "--fail-under=20")
103+
104+
session.run("coverage", "erase")
105+
106+
107+
@nox.session(python=DEFAULT_PYTHON_VERSION)
85108
def docs(session):
86109
"""Build the docs for this library."""
87110

88-
session.install("-e", ".")
89-
session.install("sphinx<3.0.0", "alabaster", "recommonmark")
111+
session.install("-e", ".[tracing]")
112+
session.install("sphinx", "alabaster", "recommonmark")
90113

91114
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
92115
session.run(
@@ -101,3 +124,40 @@ def docs(session):
101124
os.path.join("docs", ""),
102125
os.path.join("docs", "_build", "html", ""),
103126
)
127+
128+
129+
@nox.session(python=DEFAULT_PYTHON_VERSION)
130+
def docfx(session):
131+
"""Build the docfx yaml files for this library."""
132+
133+
session.install("-e", ".[tracing]")
134+
# sphinx-docfx-yaml supports up to sphinx version 1.5.5.
135+
# https://github.com/docascode/sphinx-docfx-yaml/issues/97
136+
session.install(
137+
"sphinx==1.5.5", "alabaster", "recommonmark", "sphinx-docfx-yaml"
138+
)
139+
140+
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
141+
session.run(
142+
"sphinx-build",
143+
"-T", # show full traceback on exception
144+
"-N", # no colors
145+
"-D",
146+
(
147+
"extensions=sphinx.ext.autodoc,"
148+
"sphinx.ext.autosummary,"
149+
"docfx_yaml.extension,"
150+
"sphinx.ext.intersphinx,"
151+
"sphinx.ext.coverage,"
152+
"sphinx.ext.napoleon,"
153+
"sphinx.ext.todo,"
154+
"sphinx.ext.viewcode,"
155+
"recommonmark"
156+
),
157+
"-b",
158+
"html",
159+
"-d",
160+
os.path.join("docs", "_build", "doctrees", ""),
161+
os.path.join("docs", ""),
162+
os.path.join("docs", "_build", "html", ""),
163+
)

‎tests/unit/django_spanner/test_base.py

Copy file name to clipboardExpand all lines: tests/unit/django_spanner/test_base.py
+14-4Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66

77
import sys
88
import unittest
9+
import os
910

1011
from mock_import import mock_import
1112
from unittest import mock
1213

1314

1415
@mock_import()
15-
@unittest.skipIf(sys.version_info < (3, 6), reason="Skipping Python 3.5")
16+
@unittest.skipIf(
17+
sys.version_info < (3, 6), reason="Skipping Python versions <= 3.5"
18+
)
1619
class TestBase(unittest.TestCase):
17-
PROJECT = "project"
20+
PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
1821
INSTANCE_ID = "instance_id"
1922
DATABASE_ID = "database_id"
2023
USER_AGENT = "django_spanner/2.2.0a1"
@@ -64,10 +67,10 @@ def test_get_connection_params(self):
6467
def test_get_new_connection(self):
6568
db_wrapper = self._make_one(self.settings_dict)
6669
db_wrapper.Database = mock_database = mock.MagicMock()
67-
mock_database.connect = mock_connect = mock.MagicMock()
70+
mock_database.connect = mock_connection = mock.MagicMock()
6871
conn_params = {"test_param": "dummy"}
6972
db_wrapper.get_new_connection(conn_params)
70-
mock_connect.assert_called_once_with(**conn_params)
73+
mock_connection.assert_called_once_with(**conn_params)
7174

7275
def test_init_connection_state(self):
7376
db_wrapper = self._make_one(self.settings_dict)
@@ -106,3 +109,10 @@ def test_is_usable(self):
106109

107110
mock_connection.cursor = mock.MagicMock(side_effect=Error)
108111
self.assertFalse(db_wrapper.is_usable())
112+
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()
116+
mock_connection.cursor = mock_cursor = mock.MagicMock()
117+
db_wrapper._start_transaction_under_autocommit()
118+
mock_cursor.assert_called_once_with()
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2020 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+
import sys
8+
import unittest
9+
import os
10+
11+
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+
38+
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+
with self.assertRaises(NotSupportedError):
44+
db_wrapper.runshell(parameters=self.settings_dict)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.