localstack-snapshot 0.3.1__tar.gz → 0.3.2__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 (23) hide show
  1. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/PKG-INFO +1 -1
  2. localstack_snapshot-0.3.2/localstack_snapshot/__init__.py +1 -0
  3. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/snapshots/prototype.py +22 -9
  4. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot.egg-info/PKG-INFO +1 -1
  5. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/pyproject.toml +1 -1
  6. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/tests/test_snapshots.py +62 -0
  7. localstack_snapshot-0.3.1/localstack_snapshot/__init__.py +0 -1
  8. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/LICENSE +0 -0
  9. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/README.md +0 -0
  10. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/pytest/__init__.py +0 -0
  11. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/pytest/snapshot.py +0 -0
  12. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/snapshots/__init__.py +0 -0
  13. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/snapshots/report.py +0 -0
  14. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/snapshots/transformer.py +0 -0
  15. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/snapshots/transformer_utility.py +0 -0
  16. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/util/__init__.py +0 -0
  17. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot/util/encoding.py +0 -0
  18. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot.egg-info/SOURCES.txt +0 -0
  19. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot.egg-info/dependency_links.txt +0 -0
  20. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot.egg-info/requires.txt +0 -0
  21. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/localstack_snapshot.egg-info/top_level.txt +0 -0
  22. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/setup.cfg +0 -0
  23. {localstack_snapshot-0.3.1 → localstack_snapshot-0.3.2}/tests/test_transformer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-snapshot
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Extracted snapshot testing lib for LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License:
@@ -0,0 +1 @@
1
+ __version__ = "0.3.2"
@@ -2,7 +2,9 @@ import io
2
2
  import json
3
3
  import logging
4
4
  import os
5
+ from collections.abc import Iterator
5
6
  from datetime import datetime, timezone
7
+ from enum import Enum
6
8
  from json import JSONDecodeError
7
9
  from pathlib import Path
8
10
  from re import Pattern
@@ -169,16 +171,27 @@ class SnapshotSession:
169
171
  def match_object(self, key: str, obj: object) -> None:
170
172
  def _convert_object_to_dict(obj_):
171
173
  if isinstance(obj_, dict):
172
- for key in list(obj_.keys()):
173
- if key.startswith("_"):
174
- del obj_[key]
175
- else:
176
- obj_[key] = _convert_object_to_dict(obj_[key])
177
- elif isinstance(obj_, list):
178
- for idx, val in enumerate(obj_):
179
- obj_[idx] = _convert_object_to_dict(val)
174
+ # Serialize the values of the dictionary, while skipping any private keys (starting with '_')
175
+ return {
176
+ key_: _convert_object_to_dict(obj_[key_])
177
+ for key_ in obj_
178
+ if not key_.startswith("_")
179
+ }
180
+ elif isinstance(obj_, (list, Iterator)):
181
+ return [_convert_object_to_dict(val) for val in obj_]
182
+ elif isinstance(obj_, Enum):
183
+ return obj_.value
180
184
  elif hasattr(obj_, "__dict__"):
181
- return _convert_object_to_dict(obj_.__dict__)
185
+ # This is an object - let's try to convert it to a dictionary
186
+ # A naive approach would be to use the '__dict__' object directly, but that only lists the attributes
187
+ # In order to also serialize the properties, we use the __dir__() method
188
+ # Filtering by everything that is not a method gives us both attributes and properties
189
+ # We also (still) skip private attributes/properties, so everything that starts with an underscore
190
+ return {
191
+ k: _convert_object_to_dict(getattr(obj_, k))
192
+ for k in obj_.__dir__()
193
+ if not k.startswith("_") and type(getattr(obj_, k, "")).__name__ != "method"
194
+ }
182
195
  return obj_
183
196
 
184
197
  return self.match(key, _convert_object_to_dict(obj))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-snapshot
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Extracted snapshot testing lib for LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License:
@@ -7,7 +7,7 @@ name = "localstack-snapshot"
7
7
  authors = [
8
8
  { name = "LocalStack Contributors", email = "info@localstack.cloud" }
9
9
  ]
10
- version = "0.3.1"
10
+ version = "0.3.2"
11
11
  description = "Extracted snapshot testing lib for LocalStack"
12
12
  dependencies = [
13
13
  "jsonpath-ng>1.6",
@@ -1,4 +1,5 @@
1
1
  import io
2
+ from enum import Enum
2
3
 
3
4
  import pytest
4
5
 
@@ -75,6 +76,67 @@ class TestSnapshotManager:
75
76
  sm.match_object("key_a", CustomObject(name="myname"))
76
77
  sm._assert_all()
77
78
 
79
+ def test_match_object_lists_and_iterators(self):
80
+ class CustomObject:
81
+ def __init__(self, name):
82
+ self.name = name
83
+ self.my_list = [9, 8, 7, 6, 5]
84
+ self.my_iterator = (x for x in range(5))
85
+
86
+ sm = SnapshotSession(scope_key="A", verify=True, base_file_path="", update=False)
87
+ sm.recorded_state = {
88
+ "key_a": {"name": "myname", "my_iterator": [0, 1, 2, 3, 4], "my_list": [9, 8, 7, 6, 5]}
89
+ }
90
+ sm.match_object("key_a", CustomObject(name="myname"))
91
+ sm._assert_all()
92
+
93
+ def test_match_object_include_properties(self):
94
+ class CustomObject:
95
+ def __init__(self, name):
96
+ self.name = name
97
+ self._internal = "n/a"
98
+
99
+ def some_method(self):
100
+ # method should not be serialized
101
+ return False
102
+
103
+ @property
104
+ def some_prop(self):
105
+ # properties should be serialized
106
+ return True
107
+
108
+ @property
109
+ def some_iterator(self):
110
+ for i in range(3):
111
+ yield i
112
+
113
+ @property
114
+ def _private_prop(self):
115
+ # private properties should be ignored
116
+ return False
117
+
118
+ sm = SnapshotSession(scope_key="A", verify=True, base_file_path="", update=False)
119
+ sm.recorded_state = {
120
+ "key_a": {"name": "myname", "some_prop": True, "some_iterator": [0, 1, 2]}
121
+ }
122
+ sm.match_object("key_a", CustomObject(name="myname"))
123
+ sm._assert_all()
124
+
125
+ def test_match_object_enums(self):
126
+ class TestEnum(Enum):
127
+ value1 = "Value 1"
128
+ value2 = "Value 2"
129
+
130
+ class CustomObject:
131
+ def __init__(self, name):
132
+ self.name = name
133
+ self.my_enum = TestEnum.value2
134
+
135
+ sm = SnapshotSession(scope_key="A", verify=True, base_file_path="", update=False)
136
+ sm.recorded_state = {"key_a": {"name": "myname", "my_enum": "Value 2"}}
137
+ sm.match_object("key_a", CustomObject(name="myname"))
138
+ sm._assert_all()
139
+
78
140
  def test_match_object_change(self):
79
141
  class CustomObject:
80
142
  def __init__(self, name):
@@ -1 +0,0 @@
1
- __version__ = "0.3.1"