Skip to content

Instantly share code, notes, and snippets.

@schwehr
Created November 15, 2025 20:42
Show Gist options
  • Select an option

  • Save schwehr/dc95fcc5d029a602220ddce2145f6b1b to your computer and use it in GitHub Desktop.

Select an option

Save schwehr/dc95fcc5d029a602220ddce2145f6b1b to your computer and use it in GitHub Desktop.
Draft bump_geemap_version_test.py - needs reformatting to geemap style
import builtins
import pathlib
import shutil
import sys
import tempfile
import textwrap
import unittest
from unittest import mock
from geemap.scripts import bump_geemap_version
class TestUpdatePyprojectToml(unittest.TestCase):
"""Tests for update_pyproject_toml."""
current_version = '0.36.4'
next_version = '0.36.5'
def setUp(self):
super().setUp()
self.test_dir = tempfile.mkdtemp()
self.pyproject_path = pathlib.Path(self.test_dir) / 'pyproject.toml'
def tearDown(self):
super().tearDown()
shutil.rmtree(self.test_dir)
def test_update_pyproject_toml_success(self):
"""Test successful update of pyproject.toml."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
version = "{self.current_version}"
description = "A Python package ..."
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true""")
self.pyproject_path.write_text(content)
self.assertTrue(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.next_version
)
)
new_content = self.pyproject_path.read_text()
self.assertIn(f'version = "{self.next_version}"', new_content)
self.assertIn(f'current_version = "{self.next_version}"', new_content)
self.assertNotIn(f'version = "{self.current_version}"', new_content)
self.assertNotIn(f'current_version = "{self.current_version}"', new_content)
def test_update_pyproject_toml_with_extra_section(self):
"""Test successful update with other sections present."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
version = "{self.current_version}"
description = "A Python package ..."
[another.section]
foo = "bar"
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true""")
self.pyproject_path.write_text(content)
self.assertTrue(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.next_version
)
)
new_content = self.pyproject_path.read_text()
self.assertIn(f'version = "{self.next_version}"', new_content)
self.assertIn(f'current_version = "{self.next_version}"', new_content)
def test_update_pyproject_toml_no_project_version(self):
"""Test pyproject.toml with missing project version."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
description = "A Python package ..."
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true
""")
self.pyproject_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.next_version
)
)
def test_update_pyproject_toml_no_bumpversion_version(self):
"""Test pyproject.toml with missing bumpversion version."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
version = "{self.current_version}"
description = "A Python package ..."
[tool.bumpversion]
commit = true
""")
self.pyproject_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.next_version
)
)
def test_update_pyproject_toml_no_change(self):
"""Test pyproject.toml with same version."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
version = "{self.current_version}"
description = "A Python package ..."
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true
""")
self.pyproject_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.current_version
)
)
def test_update_pyproject_toml_fail_replace(self):
"""Test pyproject.toml where version replacement fails."""
content = textwrap.dedent(f"""
[project]
name = "geemap"
[another.section]
foo = "bar"
version = "{self.current_version}"
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true""")
self.pyproject_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_pyproject_toml(
self.pyproject_path, self.next_version
)
)
class TestUpdateInitPy(unittest.TestCase):
"""Tests for update_init_py."""
current_version = '0.36.4'
next_version = '0.36.5'
def setUp(self):
super().setUp()
self.test_dir = tempfile.mkdtemp()
self.init_py_path = pathlib.Path(self.test_dir) / '__init__.py'
def tearDown(self):
super().tearDown()
shutil.rmtree(self.test_dir)
def test_update_init_py_success(self):
"""Test successful update of __init__.py."""
content = f'\n__version__ = "{self.current_version}"\n'
self.init_py_path.write_text(content)
self.assertTrue(
bump_geemap_version.update_init_py(self.init_py_path, self.next_version)
)
new_content = self.init_py_path.read_text()
self.assertIn(f'__version__ = "{self.next_version}"', new_content)
self.assertNotIn(f'__version__ = "{self.current_version}"', new_content)
def test_update_init_py_no_version(self):
"""Test __init__.py with missing version."""
content = '\nprint("hello")\n'
self.init_py_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_init_py(self.init_py_path, self.next_version)
)
def test_update_init_py_no_change(self):
"""Test __init__.py with same version."""
content = f'__version__ = "{self.current_version}"'
self.init_py_path.write_text(content)
self.assertFalse(
bump_geemap_version.update_init_py(
self.init_py_path, f'{self.current_version}'
)
)
class TestUpdateVersion(unittest.TestCase):
"""Tests for update_version."""
current_version = '0.1.0'
next_version = '0.1.1'
def setUp(self):
super().setUp()
self.test_dir = tempfile.mkdtemp()
self.repo_root = pathlib.Path(self.test_dir)
self.pyproject_path = self.repo_root / 'pyproject.toml'
self.geemap_dir = self.repo_root / 'geemap'
self.geemap_dir.mkdir()
self.init_py_path = self.geemap_dir / '__init__.py'
self.pyproject_path.write_text(textwrap.dedent(f"""
[project]
name = "geemap"
version = "{self.current_version}"
description = "A Python package ..."
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true
"""))
self.init_py_path.write_text(f'__version__ = "{self.current_version}"\\n')
new_script_file = str(self.repo_root / 'scripts' / 'bump_geemap_version.py')
self.enter_context(
mock.patch.object(
bump_geemap_version, '__file__', new_script_file
)
)
def tearDown(self):
super().tearDown()
shutil.rmtree(self.test_dir)
def test_update_version_success(self):
self.assertTrue(bump_geemap_version.update_version(self.next_version))
self.assertIn(
f'version = "{self.next_version}"', self.pyproject_path.read_text()
)
self.assertIn(
f'current_version = "{self.next_version}"',
self.pyproject_path.read_text(),
)
self.assertIn(
f'__version__ = "{self.next_version}"', self.init_py_path.read_text()
)
def test_update_version_invalid_format(self):
self.assertFalse(bump_geemap_version.update_version('invalid-version'))
def test_update_version_pyproject_missing(self):
self.pyproject_path.unlink()
self.assertFalse(bump_geemap_version.update_version(self.next_version))
def test_update_version_init_py_missing(self):
self.init_py_path.unlink()
self.assertFalse(bump_geemap_version.update_version(self.next_version))
def test_update_version_pyproject_update_fails(self):
# Missing [project] version
self.pyproject_path.write_text(textwrap.dedent(f"""
[project]
name = "geemap"
description = "A Python package ..."
[tool.bumpversion]
current_version = "{self.current_version}"
commit = true
"""))
self.assertFalse(bump_geemap_version.update_version(self.next_version))
def test_update_version_init_py_update_fails(self):
self.init_py_path.write_text('# no version here')
self.assertFalse(bump_geemap_version.update_version(self.next_version))
class TestMain(unittest.TestCase):
current_version = '0.1.0'
next_version = '0.1.1'
def setUp(self):
super().setUp()
self.mock_update_version = self.enter_context(
mock.patch.object(bump_geemap_version, 'update_version', autospec=True)
)
self.mock_exit = self.enter_context(
mock.patch.object(sys, 'exit', autospec=True)
)
self.mock_print = self.enter_context(mock.patch.object(builtins, 'print'))
self.mock_exit.side_effect = SystemExit
@mock.patch.object(sys, 'argv', ['bump_geemap_version.py', current_version])
def test_main_success(self):
self.mock_update_version.return_value = True
bump_geemap_version.main()
self.mock_update_version.assert_called_once_with(self.current_version)
self.mock_exit.assert_not_called()
@mock.patch.object(sys, 'argv', ['bump_geemap_version.py', current_version])
def test_main_update_fails(self):
self.mock_update_version.return_value = False
with self.assertRaises(SystemExit):
bump_geemap_version.main()
self.mock_update_version.assert_called_once_with(self.current_version)
self.mock_exit.assert_called_once_with(1)
@mock.patch.object(sys, 'argv', ['bump_geemap_version.py'])
def test_main_no_args(self):
with self.assertRaises(SystemExit):
bump_geemap_version.main()
self.mock_update_version.assert_not_called()
self.mock_exit.assert_called_once_with(1)
@mock.patch.object(
sys, 'argv', ['bump_geemap_version.py', current_version, 'extra']
)
def test_main_too_many_args(self):
with self.assertRaises(SystemExit):
bump_geemap_version.main()
self.mock_update_version.assert_not_called()
self.mock_exit.assert_called_once_with(1)
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment