robotframework-mock 0.8.0__tar.gz → 0.9.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 (16) hide show
  1. {robotframework_mock-0.8.0/src/robotframework_mock.egg-info → robotframework_mock-0.9.0}/PKG-INFO +28 -1
  2. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/README.md +27 -0
  3. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/setup.cfg +1 -1
  4. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/MockLibrary/__init__.py +2 -0
  5. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/MockResource/__init__.py +2 -0
  6. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/_mock_core/__init__.py +62 -1
  7. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0/src/robotframework_mock.egg-info}/PKG-INFO +28 -1
  8. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/LICENSE +0 -0
  9. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/MANIFEST.in +0 -0
  10. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/pyproject.toml +0 -0
  11. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/setup.py +0 -0
  12. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/MockCoverage/__init__.py +0 -0
  13. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/robotframework_mock.egg-info/SOURCES.txt +0 -0
  14. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/robotframework_mock.egg-info/dependency_links.txt +0 -0
  15. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/robotframework_mock.egg-info/requires.txt +0 -0
  16. {robotframework_mock-0.8.0 → robotframework_mock-0.9.0}/src/robotframework_mock.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-mock
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: A Robot Framework library for mocking keywords in unit tests
5
5
  Home-page: https://github.com/olesz/robotframework-mock
6
6
  Author: Lajos Olah
@@ -62,6 +62,7 @@ pip install -r requirements-dev.txt
62
62
  - Support for keywords with custom names via @keyword decorator
63
63
  - Verify keyword calls and call counts
64
64
  - Inspect and verify the arguments a mocked keyword was called with
65
+ - Inspect the order in which mocked keywords were called
65
66
  - Measure resource-file keyword coverage with configurable thresholds
66
67
  - Simple API with three main keywords
67
68
 
@@ -434,6 +435,32 @@ Return how many times a mocked keyword was called.
434
435
  ${count}= MockDB.Get Keyword Call Count execute_sql
435
436
  ```
436
437
 
438
+ ### Get Keyword Call Order
439
+
440
+ Return the mocked keywords in the order they were called, as a list of names.
441
+
442
+ Covers keywords mocked through the same library instance. This is what
443
+ establishes ordering *between* different mocks — an individual mock's call
444
+ history cannot show how it interleaved with its siblings.
445
+
446
+ A keyword called more than once appears once per call. Keywords that were mocked
447
+ but never called do not appear, and calls made on a keyword's return value are
448
+ not included.
449
+
450
+ **Example:**
451
+ ```robot
452
+ MockRes.Mock Keyword Init Client return_value=alias
453
+ MockRes.Mock Keyword Run Query return_value=${rows}
454
+
455
+ Fetch Data
456
+
457
+ ${order}= MockRes.Get Keyword Call Order
458
+ Should Be Equal ${order} ${{ ['Init Client', 'Run Query'] }}
459
+ ```
460
+
461
+ Use this instead of wiring a `side_effect` that appends to a list, which is the
462
+ only way to observe ordering otherwise.
463
+
437
464
  ## How It Works
438
465
 
439
466
  ### MockLibrary
@@ -38,6 +38,7 @@ pip install -r requirements-dev.txt
38
38
  - Support for keywords with custom names via @keyword decorator
39
39
  - Verify keyword calls and call counts
40
40
  - Inspect and verify the arguments a mocked keyword was called with
41
+ - Inspect the order in which mocked keywords were called
41
42
  - Measure resource-file keyword coverage with configurable thresholds
42
43
  - Simple API with three main keywords
43
44
 
@@ -410,6 +411,32 @@ Return how many times a mocked keyword was called.
410
411
  ${count}= MockDB.Get Keyword Call Count execute_sql
411
412
  ```
412
413
 
414
+ ### Get Keyword Call Order
415
+
416
+ Return the mocked keywords in the order they were called, as a list of names.
417
+
418
+ Covers keywords mocked through the same library instance. This is what
419
+ establishes ordering *between* different mocks — an individual mock's call
420
+ history cannot show how it interleaved with its siblings.
421
+
422
+ A keyword called more than once appears once per call. Keywords that were mocked
423
+ but never called do not appear, and calls made on a keyword's return value are
424
+ not included.
425
+
426
+ **Example:**
427
+ ```robot
428
+ MockRes.Mock Keyword Init Client return_value=alias
429
+ MockRes.Mock Keyword Run Query return_value=${rows}
430
+
431
+ Fetch Data
432
+
433
+ ${order}= MockRes.Get Keyword Call Order
434
+ Should Be Equal ${order} ${{ ['Init Client', 'Run Query'] }}
435
+ ```
436
+
437
+ Use this instead of wiring a `side_effect` that appends to a list, which is the
438
+ only way to observe ordering otherwise.
439
+
413
440
  ## How It Works
414
441
 
415
442
  ### MockLibrary
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = robotframework-mock
3
- version = 0.8.0
3
+ version = 0.9.0
4
4
  author = Lajos Olah
5
5
  author_email = lajos.olah.jr@gmail.com
6
6
  description = A Robot Framework library for mocking keywords in unit tests
@@ -160,6 +160,7 @@ class MockLibrary(CallInspectionMixin):
160
160
  # Create Mock object with specified behavior
161
161
  mock = Mock(return_value=return_value, side_effect=side_effect)
162
162
  self._mocks[method_name] = mock
163
+ self._track_call_order(keyword_name, mock)
163
164
 
164
165
  # Replace the method on the class or instance
165
166
  try:
@@ -194,6 +195,7 @@ class MockLibrary(CallInspectionMixin):
194
195
 
195
196
  # Clear all tracking dictionaries
196
197
  self._mocks.clear()
198
+ self._reset_call_order()
197
199
  self._original_methods.clear()
198
200
 
199
201
  @keyword
@@ -231,6 +231,7 @@ class MockResource(CallInspectionMixin):
231
231
  keyword_runner.keyword.teardown = None
232
232
  mock = Mock(return_value=return_value, side_effect=side_effect)
233
233
  self._mocks[normalize_keyword_name(keyword_name)] = mock
234
+ self._track_call_order(keyword_name, mock)
234
235
  # Tell MockCoverage this keyword's body no longer runs, so it is not
235
236
  # credited with coverage it did not earn.
236
237
  register_mocked_keyword(resource_file, keyword_name)
@@ -247,6 +248,7 @@ class MockResource(CallInspectionMixin):
247
248
  | MockRes.Reset Mocks |
248
249
  """
249
250
  self._mocks.clear()
251
+ self._reset_call_order()
250
252
  for keyword_name, source in self._mocked_sources.items():
251
253
  unregister_mocked_keyword(source, keyword_name)
252
254
  for keyword_name, items in self._original_items.items():
@@ -10,7 +10,7 @@ apart.
10
10
  # pylint: disable=invalid-name
11
11
  import os
12
12
  from typing import Any, Dict, List
13
- from unittest.mock import call
13
+ from unittest.mock import call, Mock
14
14
 
15
15
  from robot.api.deco import keyword
16
16
  from robot.utils import normalize
@@ -87,10 +87,37 @@ class CallInspectionMixin:
87
87
  - ``self._mocks``: mapping of mock key -> :class:`unittest.mock.Mock`
88
88
  - ``self._mock_key(keyword_name)``: the ``self._mocks`` key for a keyword
89
89
  name, in case the library does not key by the name as written
90
+ - ``self._call_manager`` / ``self._display_names``: created on first use by
91
+ :meth:`_track_call_order`, which the host calls for each new mock
90
92
  """
91
93
 
92
94
  _mocks: Dict[str, Any]
93
95
 
96
+ def _track_call_order(self, keyword_name: str, mock) -> None:
97
+ """Attach a mock so its calls are ordered against its siblings.
98
+
99
+ ``unittest.mock`` records calls to attached children on the parent in
100
+ invocation order, which is the only way to establish the relative order
101
+ of calls to *different* mocks - each mock's own ``call_args_list`` knows
102
+ nothing about the others.
103
+
104
+ Args:
105
+ keyword_name: Keyword name as written when mocking.
106
+ mock: The mock backing that keyword.
107
+ """
108
+ if not hasattr(self, '_call_manager'):
109
+ self._call_manager = Mock()
110
+ self._display_names = {}
111
+ key = normalize_keyword_name(keyword_name)
112
+ self._display_names[key] = keyword_name
113
+ self._call_manager.attach_mock(mock, key)
114
+
115
+ def _reset_call_order(self) -> None:
116
+ """Forget the recorded call order, called when mocks are reset."""
117
+ if hasattr(self, '_call_manager'):
118
+ del self._call_manager
119
+ del self._display_names
120
+
94
121
  def _mock_key(self, keyword_name: str) -> str:
95
122
  """Return the ``self._mocks`` key for *keyword_name*.
96
123
 
@@ -144,6 +171,40 @@ class CallInspectionMixin:
144
171
  )
145
172
  return calls[index]
146
173
 
174
+ @keyword
175
+ def get_keyword_call_order(self) -> List[str]:
176
+ """Return the mocked keywords in the order they were called.
177
+
178
+ Covers keywords mocked through *this* library instance, which is what
179
+ establishes ordering between different mocks - an individual mock's
180
+ call history cannot show how it interleaved with its siblings.
181
+
182
+ A keyword called more than once appears once per call. Keywords mocked
183
+ but never called do not appear at all.
184
+
185
+ Returns:
186
+ Keyword names, as written when mocking, in invocation order.
187
+
188
+ Example:
189
+ | MockRes.Mock Keyword | Init Client | return_value=alias |
190
+ | MockRes.Mock Keyword | Run Query | return_value=${rows} |
191
+ | Fetch Data |
192
+ | ${order}= | MockRes.Get Keyword Call Order |
193
+ | Should Be Equal | ${order} | ${{ ['Init Client', 'Run Query'] }} |
194
+ """
195
+ if not hasattr(self, '_call_manager'):
196
+ return []
197
+ order = []
198
+ for recorded in self._call_manager.mock_calls:
199
+ name = recorded[0]
200
+ # Skip nested calls such as "run_query().json()", which belong to
201
+ # the returned object rather than to a mocked keyword.
202
+ if not name or '.' in name:
203
+ continue
204
+ if name in self._display_names:
205
+ order.append(self._display_names[name])
206
+ return order
207
+
147
208
  @keyword
148
209
  def get_keyword_call_count(self, keyword_name: str) -> int:
149
210
  """Return how many times a mocked keyword was called.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-mock
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: A Robot Framework library for mocking keywords in unit tests
5
5
  Home-page: https://github.com/olesz/robotframework-mock
6
6
  Author: Lajos Olah
@@ -62,6 +62,7 @@ pip install -r requirements-dev.txt
62
62
  - Support for keywords with custom names via @keyword decorator
63
63
  - Verify keyword calls and call counts
64
64
  - Inspect and verify the arguments a mocked keyword was called with
65
+ - Inspect the order in which mocked keywords were called
65
66
  - Measure resource-file keyword coverage with configurable thresholds
66
67
  - Simple API with three main keywords
67
68
 
@@ -434,6 +435,32 @@ Return how many times a mocked keyword was called.
434
435
  ${count}= MockDB.Get Keyword Call Count execute_sql
435
436
  ```
436
437
 
438
+ ### Get Keyword Call Order
439
+
440
+ Return the mocked keywords in the order they were called, as a list of names.
441
+
442
+ Covers keywords mocked through the same library instance. This is what
443
+ establishes ordering *between* different mocks — an individual mock's call
444
+ history cannot show how it interleaved with its siblings.
445
+
446
+ A keyword called more than once appears once per call. Keywords that were mocked
447
+ but never called do not appear, and calls made on a keyword's return value are
448
+ not included.
449
+
450
+ **Example:**
451
+ ```robot
452
+ MockRes.Mock Keyword Init Client return_value=alias
453
+ MockRes.Mock Keyword Run Query return_value=${rows}
454
+
455
+ Fetch Data
456
+
457
+ ${order}= MockRes.Get Keyword Call Order
458
+ Should Be Equal ${order} ${{ ['Init Client', 'Run Query'] }}
459
+ ```
460
+
461
+ Use this instead of wiring a `side_effect` that appends to a list, which is the
462
+ only way to observe ordering otherwise.
463
+
437
464
  ## How It Works
438
465
 
439
466
  ### MockLibrary