pytest-neon 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/PKG-INFO +26 -1
  2. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/README.md +25 -0
  3. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/pyproject.toml +1 -1
  4. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/src/pytest_neon/__init__.py +1 -1
  5. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/src/pytest_neon/plugin.py +71 -18
  6. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/conftest.py +7 -2
  7. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/.env.example +0 -0
  8. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/.github/workflows/release.yml +0 -0
  9. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/.github/workflows/tests.yml +0 -0
  10. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/.gitignore +0 -0
  11. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/.neon +0 -0
  12. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/CLAUDE.md +0 -0
  13. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/LICENSE +0 -0
  14. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/src/pytest_neon/py.typed +0 -0
  15. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_branch_lifecycle.py +0 -0
  16. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_cli_options.py +0 -0
  17. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_env_var.py +0 -0
  18. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_fixture_errors.py +0 -0
  19. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_integration.py +0 -0
  20. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_reset_behavior.py +0 -0
  21. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/tests/test_skip_behavior.py +0 -0
  22. {pytest_neon-0.3.0 → pytest_neon-0.4.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-neon
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Pytest plugin for Neon database branch isolation in tests
5
5
  Project-URL: Homepage, https://github.com/zain/pytest-neon
6
6
  Project-URL: Repository, https://github.com/zain/pytest-neon
@@ -120,6 +120,7 @@ Returns a `NeonBranch` dataclass with:
120
120
  - `project_id`: The Neon project ID
121
121
  - `connection_string`: Full PostgreSQL connection URI
122
122
  - `host`: The database host
123
+ - `parent_id`: The parent branch ID (used for resets)
123
124
 
124
125
  ```python
125
126
  import os
@@ -237,6 +238,30 @@ pytest --neon-branch-expiry=0
237
238
  pytest --neon-env-var=TEST_DATABASE_URL
238
239
  ```
239
240
 
241
+ ### pyproject.toml / pytest.ini
242
+
243
+ You can also configure options in your `pyproject.toml`:
244
+
245
+ ```toml
246
+ [tool.pytest.ini_options]
247
+ neon_database = "mydb"
248
+ neon_role = "myrole"
249
+ neon_keep_branches = true
250
+ neon_branch_expiry = "300"
251
+ ```
252
+
253
+ Or in `pytest.ini`:
254
+
255
+ ```ini
256
+ [pytest]
257
+ neon_database = mydb
258
+ neon_role = myrole
259
+ neon_keep_branches = true
260
+ neon_branch_expiry = 300
261
+ ```
262
+
263
+ **Priority order**: CLI options > environment variables > ini settings > defaults
264
+
240
265
  ## CI/CD Integration
241
266
 
242
267
  ### GitHub Actions
@@ -78,6 +78,7 @@ Returns a `NeonBranch` dataclass with:
78
78
  - `project_id`: The Neon project ID
79
79
  - `connection_string`: Full PostgreSQL connection URI
80
80
  - `host`: The database host
81
+ - `parent_id`: The parent branch ID (used for resets)
81
82
 
82
83
  ```python
83
84
  import os
@@ -195,6 +196,30 @@ pytest --neon-branch-expiry=0
195
196
  pytest --neon-env-var=TEST_DATABASE_URL
196
197
  ```
197
198
 
199
+ ### pyproject.toml / pytest.ini
200
+
201
+ You can also configure options in your `pyproject.toml`:
202
+
203
+ ```toml
204
+ [tool.pytest.ini_options]
205
+ neon_database = "mydb"
206
+ neon_role = "myrole"
207
+ neon_keep_branches = true
208
+ neon_branch_expiry = "300"
209
+ ```
210
+
211
+ Or in `pytest.ini`:
212
+
213
+ ```ini
214
+ [pytest]
215
+ neon_database = mydb
216
+ neon_role = myrole
217
+ neon_keep_branches = true
218
+ neon_branch_expiry = 300
219
+ ```
220
+
221
+ **Priority order**: CLI options > environment variables > ini settings > defaults
222
+
198
223
  ## CI/CD Integration
199
224
 
200
225
  ### GitHub Actions
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pytest-neon"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "Pytest plugin for Neon database branch isolation in tests"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -9,7 +9,7 @@ from pytest_neon.plugin import (
9
9
  neon_engine,
10
10
  )
11
11
 
12
- __version__ = "0.3.0"
12
+ __version__ = "0.4.0"
13
13
  __all__ = [
14
14
  "NeonBranch",
15
15
  "neon_branch",
@@ -30,9 +30,10 @@ class NeonBranch:
30
30
 
31
31
 
32
32
  def pytest_addoption(parser: pytest.Parser) -> None:
33
- """Add Neon-specific command line options."""
33
+ """Add Neon-specific command line options and ini settings."""
34
34
  group = parser.getgroup("neon", "Neon database branching")
35
35
 
36
+ # CLI options
36
37
  group.addoption(
37
38
  "--neon-api-key",
38
39
  dest="neon_api_key",
@@ -51,13 +52,11 @@ def pytest_addoption(parser: pytest.Parser) -> None:
51
52
  group.addoption(
52
53
  "--neon-database",
53
54
  dest="neon_database",
54
- default="neondb",
55
55
  help="Database name (default: neondb)",
56
56
  )
57
57
  group.addoption(
58
58
  "--neon-role",
59
59
  dest="neon_role",
60
- default="neondb_owner",
61
60
  help="Database role (default: neondb_owner)",
62
61
  )
63
62
  group.addoption(
@@ -70,7 +69,6 @@ def pytest_addoption(parser: pytest.Parser) -> None:
70
69
  "--neon-branch-expiry",
71
70
  dest="neon_branch_expiry",
72
71
  type=int,
73
- default=DEFAULT_BRANCH_EXPIRY_SECONDS,
74
72
  help=(
75
73
  f"Branch auto-expiry in seconds "
76
74
  f"(default: {DEFAULT_BRANCH_EXPIRY_SECONDS}). Set to 0 to disable."
@@ -79,19 +77,62 @@ def pytest_addoption(parser: pytest.Parser) -> None:
79
77
  group.addoption(
80
78
  "--neon-env-var",
81
79
  dest="neon_env_var",
82
- default="DATABASE_URL",
83
80
  help="Environment variable to set with connection string (default: DATABASE_URL)", # noqa: E501
84
81
  )
85
82
 
83
+ # INI file settings (pytest.ini, pyproject.toml, etc.)
84
+ parser.addini("neon_api_key", "Neon API key", default=None)
85
+ parser.addini("neon_project_id", "Neon project ID", default=None)
86
+ parser.addini("neon_parent_branch", "Parent branch ID", default=None)
87
+ parser.addini("neon_database", "Database name", default="neondb")
88
+ parser.addini("neon_role", "Database role", default="neondb_owner")
89
+ parser.addini(
90
+ "neon_keep_branches",
91
+ "Don't delete branches after tests",
92
+ type="bool",
93
+ default=False,
94
+ )
95
+ parser.addini(
96
+ "neon_branch_expiry",
97
+ "Branch auto-expiry in seconds",
98
+ default=str(DEFAULT_BRANCH_EXPIRY_SECONDS),
99
+ )
100
+ parser.addini(
101
+ "neon_env_var",
102
+ "Environment variable for connection string",
103
+ default="DATABASE_URL",
104
+ )
105
+
86
106
 
87
107
  def _get_config_value(
88
- config: pytest.Config, option: str, env_var: str, default: str | None = None
108
+ config: pytest.Config,
109
+ option: str,
110
+ env_var: str,
111
+ ini_name: str | None = None,
112
+ default: str | None = None,
89
113
  ) -> str | None:
90
- """Get config value from CLI option, env var, or default."""
114
+ """Get config value from CLI option, env var, ini setting, or default.
115
+
116
+ Priority order: CLI option > environment variable > ini setting > default
117
+ """
118
+ # 1. CLI option (highest priority)
91
119
  value = config.getoption(option, default=None)
92
120
  if value is not None:
93
121
  return value
94
- return os.environ.get(env_var, default)
122
+
123
+ # 2. Environment variable
124
+ env_value = os.environ.get(env_var)
125
+ if env_value is not None:
126
+ return env_value
127
+
128
+ # 3. INI setting (pytest.ini, pyproject.toml, etc.)
129
+ if ini_name is not None:
130
+ ini_value = config.getini(ini_name)
131
+ if ini_value:
132
+ return ini_value
133
+
134
+ # 4. Default
135
+ return default
95
136
 
96
137
 
97
138
  def _create_neon_branch(
@@ -104,20 +145,32 @@ def _create_neon_branch(
104
145
  """
105
146
  config = request.config
106
147
 
107
- api_key = _get_config_value(config, "neon_api_key", "NEON_API_KEY")
108
- project_id = _get_config_value(config, "neon_project_id", "NEON_PROJECT_ID")
148
+ api_key = _get_config_value(config, "neon_api_key", "NEON_API_KEY", "neon_api_key")
149
+ project_id = _get_config_value(
150
+ config, "neon_project_id", "NEON_PROJECT_ID", "neon_project_id"
151
+ )
109
152
  parent_branch_id = _get_config_value(
110
- config, "neon_parent_branch", "NEON_PARENT_BRANCH_ID"
153
+ config, "neon_parent_branch", "NEON_PARENT_BRANCH_ID", "neon_parent_branch"
111
154
  )
112
155
  database_name = _get_config_value(
113
- config, "neon_database", "NEON_DATABASE", "neondb"
156
+ config, "neon_database", "NEON_DATABASE", "neon_database", "neondb"
114
157
  )
115
- role_name = _get_config_value(config, "neon_role", "NEON_ROLE", "neondb_owner")
116
- keep_branches = config.getoption("neon_keep_branches", default=False)
117
- branch_expiry = config.getoption(
118
- "neon_branch_expiry", default=DEFAULT_BRANCH_EXPIRY_SECONDS
158
+ role_name = _get_config_value(
159
+ config, "neon_role", "NEON_ROLE", "neon_role", "neondb_owner"
160
+ )
161
+
162
+ # For boolean/int options, check CLI first, then ini
163
+ keep_branches = config.getoption("neon_keep_branches", default=None)
164
+ if keep_branches is None:
165
+ keep_branches = config.getini("neon_keep_branches")
166
+
167
+ branch_expiry = config.getoption("neon_branch_expiry", default=None)
168
+ if branch_expiry is None:
169
+ branch_expiry = int(config.getini("neon_branch_expiry"))
170
+
171
+ env_var_name = _get_config_value(
172
+ config, "neon_env_var", "", "neon_env_var", "DATABASE_URL"
119
173
  )
120
- env_var_name = config.getoption("neon_env_var", default="DATABASE_URL")
121
174
 
122
175
  if not api_key:
123
176
  pytest.skip(
@@ -301,7 +354,7 @@ def neon_branch(
301
354
  conn_string = neon_branch.connection_string
302
355
  """
303
356
  config = request.config
304
- api_key = _get_config_value(config, "neon_api_key", "NEON_API_KEY")
357
+ api_key = _get_config_value(config, "neon_api_key", "NEON_API_KEY", "neon_api_key")
305
358
 
306
359
  # Validate that branch has a parent for reset functionality
307
360
  if not _neon_branch_for_reset.parent_id:
@@ -19,8 +19,13 @@ from pytest_neon.plugin import NeonBranch
19
19
  @pytest.fixture(scope="module")
20
20
  def neon_branch(request):
21
21
  """Mock neon_branch fixture for testing."""
22
- keep_branches = request.config.getoption("neon_keep_branches", default=False)
23
- env_var_name = request.config.getoption("neon_env_var", default="DATABASE_URL")
22
+ keep_branches = request.config.getoption("neon_keep_branches", default=None)
23
+ if keep_branches is None:
24
+ keep_branches = False
25
+
26
+ env_var_name = request.config.getoption("neon_env_var", default=None)
27
+ if env_var_name is None:
28
+ env_var_name = "DATABASE_URL"
24
29
 
25
30
  branch_info = NeonBranch(
26
31
  branch_id="br-mock-123",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes