1+ import copy
12import io
23from enum import Enum
34
@@ -268,48 +269,44 @@ def test_non_homogeneous_list(self):
268269 sm .match ("key1" , [{"key2" : "value1" }, "value2" , 3 ])
269270 sm ._assert_all ()
270271
271- def test_list_as_last_node_in_skip_verification_path (self ):
272+ # skipping mutates the recorded and observed state, so every assertion needs a new session
273+
274+ @staticmethod
275+ def _new_session (recorded : dict , observed : dict ) -> SnapshotSession :
272276 sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
273- sm .recorded_state = {"key_a" : {"aaa" : ["item1" , "item2" , "item3" ]}}
274- sm .match (
275- "key_a" ,
276- {"aaa" : ["item1" , "different-value" ]},
277- )
277+ sm .recorded_state = {"key_a" : copy .deepcopy (recorded )}
278+ sm .match ("key_a" , copy .deepcopy (observed ))
279+ return sm
280+
281+ def test_list_as_last_node_in_skip_verification_path (self ):
282+ recorded = {"aaa" : ["item1" , "item2" , "item3" ]}
283+ observed = {"aaa" : ["item1" , "different-value" ]}
278284
279285 with pytest .raises (Exception ) as ctx : # asserts it fail without skipping
280- sm ._assert_all ()
286+ self . _new_session ( recorded , observed ) ._assert_all ()
281287 ctx .match ("Parity snapshot failed" )
282288
283289 skip_path = ["$..aaa[1]" , "$..aaa[2]" ]
284- sm ._assert_all (skip_verification_paths = skip_path )
285-
286- skip_path = ["$..aaa.1" , "$..aaa.2" ]
287- sm ._assert_all (skip_verification_paths = skip_path )
290+ self ._new_session (recorded , observed )._assert_all (skip_verification_paths = skip_path )
288291
289292 def test_list_as_last_node_in_skip_verification_path_complex (self ):
290- sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
291- sm .recorded_state = {
292- "key_a" : {
293- "aaa" : [
294- {"aab" : ["aac" , "aad" ]},
295- {"aab" : ["aac" , "aad" ]},
296- {"aab" : ["aac" , "aad" ]},
297- ]
298- }
293+ recorded = {
294+ "aaa" : [
295+ {"aab" : ["aac" , "aad" ]},
296+ {"aab" : ["aac" , "aad" ]},
297+ {"aab" : ["aac" , "aad" ]},
298+ ]
299+ }
300+ observed = {
301+ "aaa" : [
302+ {"aab" : ["aac" , "bad-value" ], "bbb" : "value" },
303+ {"aab" : ["aac" , "aad" , "bad-value" ]},
304+ {"aab" : ["bad-value" , "aad" ]},
305+ ]
299306 }
300- sm .match (
301- "key_a" ,
302- {
303- "aaa" : [
304- {"aab" : ["aac" , "bad-value" ], "bbb" : "value" },
305- {"aab" : ["aac" , "aad" , "bad-value" ]},
306- {"aab" : ["bad-value" , "aad" ]},
307- ]
308- },
309- )
310307
311308 with pytest .raises (Exception ) as ctx : # asserts it fail without skipping
312- sm ._assert_all ()
309+ self . _new_session ( recorded , observed ) ._assert_all ()
313310 ctx .match ("Parity snapshot failed" )
314311
315312 skip_path = [
@@ -318,86 +315,75 @@ def test_list_as_last_node_in_skip_verification_path_complex(self):
318315 "$..aaa[1].aab[2]" ,
319316 "$..aaa[2].aab[0]" ,
320317 ]
321- sm ._assert_all (skip_verification_paths = skip_path )
322-
323- skip_path = [
324- "$..aaa.0..aab.1" ,
325- "$..aaa.0..bbb" ,
326- "$..aaa.1..aab.2" ,
327- "$..aaa.2..aab.0" ,
328- ]
329- sm ._assert_all (skip_verification_paths = skip_path )
318+ self ._new_session (recorded , observed )._assert_all (skip_verification_paths = skip_path )
330319
331320 def test_list_as_mid_node_in_skip_verification_path (self ):
332- sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
333- sm .recorded_state = {"key_a" : {"aaa" : [{"aab" : "value1" }, {"aab" : "value2" }]}}
334- sm .match (
335- "key_a" ,
336- {"aaa" : [{"aab" : "value1" }, {"aab" : "bad-value" }]},
337- )
321+ recorded = {"aaa" : [{"aab" : "value1" }, {"aab" : "value2" }]}
322+ observed = {"aaa" : [{"aab" : "value1" }, {"aab" : "bad-value" }]}
338323
339324 with pytest .raises (Exception ) as ctx : # asserts it fail without skipping
340- sm ._assert_all ()
325+ self . _new_session ( recorded , observed ) ._assert_all ()
341326 ctx .match ("Parity snapshot failed" )
342327
343328 skip_path = ["$..aaa[1].aab" ]
344- sm ._assert_all (skip_verification_paths = skip_path )
329+ self ._new_session (recorded , observed )._assert_all (skip_verification_paths = skip_path )
330+
331+ @pytest .mark .parametrize (
332+ "skip_path" ,
333+ [
334+ ["$..aaa[2][0]" ],
335+ # this will actually skip almost everything, as it will match every first element of any list inside `aaa`
336+ ["$..aaa..[0]" ],
337+ ],
338+ )
339+ def test_list_as_last_node_in_skip_verification_path_nested (self , skip_path ):
340+ recorded = {"aaa" : ["bbb" , "ccc" , ["ddd" , "eee" , ["fff" , "ggg" ]]]}
341+ observed = {"aaa" : ["bbb" , "ccc" , ["bad-value" , "eee" , ["fff" , "ggg" ]]]}
345342
346- skip_path = ["$..aaa.1.aab" ]
347- sm ._assert_all (skip_verification_paths = skip_path )
343+ with pytest .raises (Exception ) as ctx : # asserts it fail without skipping
344+ self ._new_session (recorded , observed )._assert_all ()
345+ ctx .match ("Parity snapshot failed" )
348346
349- def test_list_as_last_node_in_skip_verification_path_nested (self ):
350- sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
351- sm .recorded_state = {
352- "key_a" : {
353- "aaa" : [
354- "bbb" ,
355- "ccc" ,
356- [
357- "ddd" ,
358- "eee" ,
359- [
360- "fff" ,
361- "ggg" ,
362- ],
363- ],
364- ]
347+ self ._new_session (recorded , observed )._assert_all (skip_verification_paths = skip_path )
348+
349+ @pytest .mark .parametrize (
350+ "key" ,
351+ ["with space" , "Key%" , "00" , "10" , "a.b" , "aws:SourceArn" , "Ünïcode" , "x-amz-id" ],
352+ )
353+ def test_special_characters_in_skip_verification_path (self , key ):
354+ def _new_session ():
355+ # use a new session for every assertion, as skipping mutates the recorded and observed state
356+ sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
357+ sm .recorded_state = {
358+ "key_a" : {key : {"Inner" : [{key : "value" , "other" : "same" }]}, "aaa" : "same" }
365359 }
366- }
367- sm .match (
368- "key_a" ,
369- {
370- "aaa" : [
371- "bbb" ,
372- "ccc" ,
373- [
374- "bad-value" ,
375- "eee" ,
376- [
377- "fff" ,
378- "ggg" ,
379- ],
380- ],
381- ]
382- },
383- )
360+ sm .match (
361+ "key_a" , {key : {"Inner" : [{key : "bad-value" , "other" : "same" }]}, "aaa" : "same" }
362+ )
363+ return sm
384364
385365 with pytest .raises (Exception ) as ctx : # asserts it fail without skipping
386- sm ._assert_all ()
366+ _new_session () ._assert_all ()
387367 ctx .match ("Parity snapshot failed" )
388368
389- skip_path = ["$..aaa[2][0]" ]
390- sm ._assert_all (skip_verification_paths = skip_path )
369+ # the key is used as an intermediate node as well as the last node
370+ _new_session ()._assert_all (skip_verification_paths = [f"$..'{ key } '.Inner[0].'{ key } '" ])
371+ _new_session ()._assert_all (skip_verification_paths = [f"$..Inner[*].'{ key } '" ])
372+ _new_session ()._assert_all (skip_verification_paths = [f"$..'{ key } '" ])
391373
392- skip_path = ["$..aaa.2[0]" ]
393- sm ._assert_all (skip_verification_paths = skip_path )
374+ def test_skip_verification_path_with_filter (self ):
375+ def _new_session ():
376+ sm = SnapshotSession (scope_key = "A" , verify = True , base_file_path = "" , update = False )
377+ sm .recorded_state = {"key_a" : {"aaa" : [{"id" : "1" , "v" : "a" }, {"id" : "2" , "v" : "b" }]}}
378+ sm .match ("key_a" , {"aaa" : [{"id" : "1" , "v" : "a" }, {"id" : "2" , "v" : "bad-value" }]})
379+ return sm
394380
395- # these 2 will actually skip almost everything, as they will match every first element of any list inside `aaa`
396- skip_path = [ "$..aaa..[0]" ]
397- sm . _assert_all ( skip_verification_paths = skip_path )
381+ with pytest . raises ( Exception ) as ctx : # asserts it fail without skipping
382+ _new_session (). _assert_all ()
383+ ctx . match ( "Parity snapshot failed" )
398384
399- skip_path = ["$..aaa..0" ]
400- sm ._assert_all (skip_verification_paths = skip_path )
385+ _new_session (). _assert_all ( skip_verification_paths = ["$..aaa[?(@.id == '2')].v" ])
386+ _new_session () ._assert_all (skip_verification_paths = [ "$..aaa[?(@.id == '2')]" ] )
401387
402388
403389def test_json_diff_format ():
0 commit comments