Skip to content

Commit 4031bcc

Browse files
authored
Merge pull request #2 from onefloid/new-release-0.1.5
New release 0.1.5
2 parents 2db198e + a1e8db8 commit 4031bcc

File tree

16 files changed

+329
-15
lines changed

16 files changed

+329
-15
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## v0.1.5 - 2025-16-01
4+
5+
### Features
6+
7+
- New command: `cube exists`
8+
- New command: `view exists`
9+
- New command: `dimension list`
10+
- New command: `dimension exists`
11+
- New command: `subset list`
12+
- New command: `subset exists`
13+
14+
15+
### Chore
16+
17+
- Improved testing
18+
319
## v0.1.4 - 2024-11-29
420

521
### Features

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,16 @@ tm1cli process dump <name> --folder <path> --format <json|yaml>
5252
tm1cli process load <name> --folder <path> --format <json|yaml>
5353

5454
tm1cli cube list
55+
tm1cli cube exists <cube_name>
56+
57+
tm1cli dimension list
58+
tm1cli dimension exists <dimension_name>
5559

5660
tm1cli view list <cube_name>
61+
tm1cli view exists <cube_name> <view_name>
62+
63+
tm1cli subset list <dimension_name>
64+
tm1cli subset exists <dimension_name> <subset_name>
5765
```
5866

5967
### All Available Commands

poetry.lock

Lines changed: 18 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "tm1cli"
3-
version = "0.1.4"
3+
version = "0.1.5"
44
description = "A command-line interface (CLI) tool for interacting with TM1 servers using TM1py."
55
authors = ["onefloid <onefloid@gmx.de>"]
66
license = "MIT License"
@@ -17,6 +17,7 @@ pyyaml = "^6.0.2"
1717
isort = "^5.13.2"
1818
pytest = "^8.3.3"
1919
pylint = "^3.3.1"
20+
pytest-mock = "^3.14.0"
2021

2122
[tool.poetry.scripts]
2223
tm1cli = "tm1cli.main:app"

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from TM1py import Process
2+
3+
4+
class MockedCubeService:
5+
cubes = ["Cube1", "Cube2"]
6+
7+
def get_all_names(self, cube_name: str):
8+
return self.cubes
9+
10+
def exists(self, cube_name: str):
11+
return cube_name in self.cubes
12+
13+
14+
class MockedViewService:
15+
16+
def get_all_names(self, cube_name: str):
17+
return ["View1", "View2", "View3"]
18+
19+
def exists(self, cube_name: str, view_name: str, private: bool):
20+
if "not" in view_name.lower():
21+
return False
22+
else:
23+
return True
24+
25+
26+
class MockedDimensionService:
27+
def get_all_names(self, skip_control_dims: bool):
28+
return ["Dimension1", "Dimension2", "Dimension3"]
29+
30+
def exists(self, dimension_name: str):
31+
if "not" in dimension_name.lower():
32+
return False
33+
else:
34+
return True
35+
36+
37+
class MockedSubsetService:
38+
def get_all_names(self, dimension_name: str):
39+
return ["Subset1", "Subset2", "Subset3"]
40+
41+
def exists(self, dimension_name: str, subset_name: str, private: bool):
42+
if "not" in subset_name.lower():
43+
return False
44+
else:
45+
return True
46+
47+
48+
class MockedProcessService:
49+
def exists(self, process_name: str):
50+
return False if "not" in process_name else True
51+
52+
def get(self, process_name: str):
53+
return Process(process_name)
54+
55+
def update_or_create(self, process: Process):
56+
return f"Process {process.name} was tested mocked."
57+
58+
59+
class MockedTM1Service:
60+
def __init__(self, **kwargs) -> None:
61+
self.views = MockedViewService()
62+
self.processes = MockedProcessService()
63+
self.cubes = MockedCubeService()
64+
self.dimensions = MockedDimensionService()
65+
self.subsets = MockedSubsetService()
66+
67+
def __enter__(self):
68+
"""
69+
Context manager entry point.
70+
"""
71+
return self
72+
73+
def __exit__(self, exc_type, exc_value, traceback):
74+
"""
75+
Context manager exit point. Clean up resources if needed.
76+
"""
77+
pass

tests/test_cmd_cubes.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import pytest
22
from typer.testing import CliRunner
33

4+
from tests.conftest import MockedTM1Service
45
from tm1cli.main import app
56

67
runner = CliRunner()
78

89

910
@pytest.mark.parametrize("command", ["list", "ls"])
10-
def test_cube_list(command):
11+
def test_cube_list(mocker, command):
12+
mocker.patch("tm1cli.commands.cube.TM1Service", MockedTM1Service)
1113
result = runner.invoke(app, ["cube", command])
1214
assert result.exit_code == 0
1315
assert isinstance(result.stdout, str)
16+
assert result.stdout == "Cube1\nCube2\n"
17+
18+
19+
def test_cube_exists(mocker):
20+
mocker.patch("tm1cli.commands.cube.TM1Service", MockedTM1Service)
21+
result = runner.invoke(app, ["cube", "exists", "Cube1"])
22+
assert result.exit_code == 0
23+
assert isinstance(result.stdout, str)
24+
assert result.stdout == "True\n"

tests/test_cmd_dimension.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import pytest
2+
from typer.testing import CliRunner
3+
4+
from tests.conftest import MockedTM1Service
5+
from tm1cli.main import app
6+
7+
runner = CliRunner()
8+
9+
10+
@pytest.mark.parametrize("command", ["list", "ls"])
11+
def test_dimension_list(mocker, command):
12+
mocker.patch("tm1cli.commands.dimension.TM1Service", MockedTM1Service)
13+
result = runner.invoke(app, ["dimension", command])
14+
assert result.exit_code == 0
15+
assert isinstance(result.stdout, str)
16+
assert result.stdout == "Dimension1\nDimension2\nDimension3\n"
17+
18+
19+
def test_dimension_exists(mocker):
20+
mocker.patch("tm1cli.commands.dimension.TM1Service", MockedTM1Service)
21+
result = runner.invoke(app, ["dimension", "exists", "Dimension1"])
22+
assert result.exit_code == 0
23+
assert isinstance(result.stdout, str)
24+
assert result.stdout == "True\n"

tests/test_cmd_subset.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import pytest
2+
from typer.testing import CliRunner
3+
4+
from tests.conftest import MockedTM1Service
5+
from tm1cli.main import app
6+
7+
runner = CliRunner()
8+
9+
10+
@pytest.mark.parametrize("command", ["list", "ls"])
11+
def test_subset_list(mocker, command):
12+
mocker.patch("tm1cli.commands.subset.TM1Service", MockedTM1Service)
13+
result = runner.invoke(app, ["subset", command, "Dimension1"])
14+
assert result.exit_code == 0
15+
assert isinstance(result.stdout, str)
16+
assert result.stdout == "Subset1\nSubset2\nSubset3\n"
17+
18+
19+
def test_subset_exists(mocker):
20+
mocker.patch("tm1cli.commands.subset.TM1Service", MockedTM1Service)
21+
result = runner.invoke(app, ["subset", "exists", "Dimension1", "Subset1"])
22+
assert result.exit_code == 0
23+
assert isinstance(result.stdout, str)
24+
assert result.stdout == "True\n"

tests/test_cmd_view.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,30 @@
33

44
from tm1cli.main import app
55

6+
from .conftest import MockedTM1Service
7+
68
runner = CliRunner()
79

810

9-
@pytest.mark.parametrize("command", ["list", "ls"])
10-
def test_cube_list(command):
11-
result = runner.invoke(
12-
app,
13-
[
14-
"view",
15-
command,
16-
"TM1py_tests_annotations_0f680909_74b1_11ef_b4ba_546ceb97bbfb",
17-
],
18-
)
11+
@pytest.mark.parametrize(
12+
"options",
13+
[("not", "", "False"), ("example", "-p", "True"), ("not", "--private", "False")],
14+
)
15+
def test_view_exists(mocker, options):
16+
mocker.patch("tm1cli.commands.view.TM1Service", MockedTM1Service)
17+
if options[1]:
18+
result = runner.invoke(app, ["view", "exists", "example_cube", options[0]])
19+
else:
20+
result = runner.invoke(app, ["view", "exists", "example_cube", options[:1]])
21+
assert result.exit_code == 0
22+
assert isinstance(result.stdout, str)
23+
assert result.stdout == f"{options[2]}\n"
24+
25+
26+
def test_view_list(mocker):
27+
mocker.patch("tm1cli.commands.view.TM1Service", MockedTM1Service)
28+
result = runner.invoke(app, ["view", "list", "example_cube"])
29+
1930
assert result.exit_code == 0
2031
assert isinstance(result.stdout, str)
32+
assert result.stdout == "View1\nView2\nView3\n"

0 commit comments

Comments
 (0)