Przeglądaj źródła

Add additional tests for complete coverage (#303).

Dan Helfman 2 miesięcy temu
rodzic
commit
975a6e4540

+ 1 - 1
borgmatic/borg/create.py

@@ -196,7 +196,7 @@ def check_all_root_patterns_exist(patterns):
 
 
     if missing_paths:
     if missing_paths:
         raise ValueError(
         raise ValueError(
-            f"Source directories / root pattern paths do not exist: {', '.join(missing_paths)}"
+            f"Source directories or root pattern paths do not exist: {', '.join(missing_paths)}"
         )
         )
 
 
 
 

+ 2 - 3
borgmatic/commands/arguments.py

@@ -1,7 +1,6 @@
 import collections
 import collections
 import io
 import io
 import itertools
 import itertools
-import json
 import re
 import re
 import sys
 import sys
 from argparse import ArgumentParser
 from argparse import ArgumentParser
@@ -377,7 +376,7 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name):
             registry_name
             registry_name
             for registry_name, action_type in arguments_group._registries['action'].items()
             for registry_name, action_type in arguments_group._registries['action'].items()
             # Not using isinstance() here because we only want an exact match—no parent classes.
             # Not using isinstance() here because we only want an exact match—no parent classes.
-            if type(argument_action) == action_type
+            if type(argument_action) is action_type
         )
         )
     except StopIteration:
     except StopIteration:
         return
         return
@@ -492,7 +491,7 @@ def add_arguments_from_schema(arguments_group, schema, unparsed_arguments, names
 
 
     # As a UX nicety, allow boolean options that have a default of false to have command-line flags
     # As a UX nicety, allow boolean options that have a default of false to have command-line flags
     # without values.
     # without values.
-    if schema_type == 'boolean' and schema.get('default') == False:
+    if schema_type == 'boolean' and schema.get('default') is False:
         arguments_group.add_argument(
         arguments_group.add_argument(
             full_flag_name,
             full_flag_name,
             action='store_true',
             action='store_true',

+ 13 - 9
borgmatic/config/schema.py

@@ -23,6 +23,16 @@ def get_properties(schema):
     return schema.get('properties', {})
     return schema.get('properties', {})
 
 
 
 
+SCHEMA_TYPE_TO_PYTHON_TYPE = {
+    'array': list,
+    'boolean': bool,
+    'integer': int,
+    'number': decimal.Decimal,
+    'object': dict,
+    'string': str,
+}
+
+
 def parse_type(schema_type, **overrides):
 def parse_type(schema_type, **overrides):
     '''
     '''
     Given a schema type as a string, return the corresponding Python type.
     Given a schema type as a string, return the corresponding Python type.
@@ -34,14 +44,7 @@ def parse_type(schema_type, **overrides):
     '''
     '''
     try:
     try:
         return dict(
         return dict(
-            {
-                'array': list,
-                'boolean': bool,
-                'integer': int,
-                'number': decimal.Decimal,
-                'object': dict,
-                'string': str,
-            },
+            SCHEMA_TYPE_TO_PYTHON_TYPE,
             **overrides,
             **overrides,
         )[schema_type]
         )[schema_type]
     except KeyError:
     except KeyError:
@@ -54,7 +57,8 @@ def compare_types(schema_type, target_types, match=any):
     target type strings, return whether every schema type is in the set of target types.
     target type strings, return whether every schema type is in the set of target types.
 
 
     If the schema type is a list of strings, use the given match function (such as any or all) to
     If the schema type is a list of strings, use the given match function (such as any or all) to
-    compare elements.
+    compare elements. For instance, if match is given as all, then every element of the schema_type
+    list must be in the target types.
     '''
     '''
     if isinstance(schema_type, list):
     if isinstance(schema_type, list):
         if match(element_schema_type in target_types for element_schema_type in schema_type):
         if match(element_schema_type in target_types for element_schema_type in schema_type):

+ 1 - 1
borgmatic/config/validate.py

@@ -21,7 +21,7 @@ def schema_filename():
         return schema_path
         return schema_path
 
 
 
 
-def load_schema(schema_path):
+def load_schema(schema_path):  # pragma: no cover
     '''
     '''
     Given a schema filename path, load the schema and return it as a dict.
     Given a schema filename path, load the schema and return it as a dict.
 
 

+ 6 - 1
tests/integration/commands/test_arguments.py

@@ -14,7 +14,12 @@ def test_make_argument_description_with_array_adds_example():
             },
             },
             flag_name='flag',
             flag_name='flag',
         )
         )
-        == 'Thing. Example value: "[1, \'- foo\', bar: baz]"'
+        # Apparently different versions of ruamel.yaml serialize this
+        # differently.
+        in (
+            'Thing. Example value: "[1, \'- foo\', bar: baz]"'
+            'Thing. Example value: "[1, \'- foo\', {bar: baz}]"'
+        )
     )
     )
 
 
 
 

+ 0 - 1
tests/integration/config/test_arguments.py

@@ -1,5 +1,4 @@
 import pytest
 import pytest
-from flexmock import flexmock
 
 
 from borgmatic.config import arguments as module
 from borgmatic.config import arguments as module
 
 

+ 2 - 6
tests/unit/config/test_arguments.py

@@ -175,9 +175,7 @@ def test_prepare_arguments_for_config_skips_option_with_none_value():
                 'other_option': {'type': 'string'},
                 'other_option': {'type': 'string'},
             },
             },
         },
         },
-    ) == (
-        (('other_option',), 'value2'),
-    )
+    ) == ((('other_option',), 'value2'),)
 
 
 
 
 def test_prepare_arguments_for_config_skips_option_missing_from_schema():
 def test_prepare_arguments_for_config_skips_option_missing_from_schema():
@@ -190,6 +188,4 @@ def test_prepare_arguments_for_config_skips_option_missing_from_schema():
                 'other_option': {'type': 'string'},
                 'other_option': {'type': 'string'},
             },
             },
         },
         },
-    ) == (
-        (('other_option',), 'value2'),
-    )
+    ) == ((('other_option',), 'value2'),)

+ 0 - 1
tests/unit/config/test_generate.py

@@ -2,7 +2,6 @@ import pytest
 from flexmock import flexmock
 from flexmock import flexmock
 
 
 from borgmatic.config import generate as module
 from borgmatic.config import generate as module
-import borgmatic.config.schema
 
 
 
 
 def test_schema_to_sample_configuration_generates_config_map_with_examples():
 def test_schema_to_sample_configuration_generates_config_map_with_examples():

+ 5 - 0
tests/unit/config/test_normalize.py

@@ -359,6 +359,11 @@ def test_normalize_commands_moves_individual_command_hooks_to_unified_commands(
             {'repositories': [{'path': '/repo', 'label': 'foo'}]},
             {'repositories': [{'path': '/repo', 'label': 'foo'}]},
             False,
             False,
         ),
         ),
+        (
+            {'repositories': [{'path': None, 'label': 'foo'}]},
+            {'repositories': []},
+            False,
+        ),
         (
         (
             {'prefix': 'foo'},
             {'prefix': 'foo'},
             {'prefix': 'foo'},
             {'prefix': 'foo'},

+ 83 - 0
tests/unit/config/test_schema.py

@@ -1,3 +1,5 @@
+import pytest
+
 from borgmatic.config import schema as module
 from borgmatic.config import schema as module
 
 
 
 
@@ -75,3 +77,84 @@ def test_get_properties_interleaves_oneof_list_properties():
             ('field3', {'example': 'Example 3'}),
             ('field3', {'example': 'Example 3'}),
         ]
         ]
     )
     )
+
+
+def test_parse_type_maps_schema_type_to_python_type():
+    module.parse_type('boolean') == bool
+
+
+def test_parse_type_with_unknown_schema_type_raises():
+    with pytest.raises(ValueError):
+        module.parse_type('what')
+
+
+def test_parse_type_respect_overrides_when_mapping_types():
+    module.parse_type('boolean', boolean=int) == int
+
+
+@pytest.mark.parametrize(
+    'schema_type,target_types,match,expected_result',
+    (
+        (
+            'string',
+            {'integer', 'string', 'boolean'},
+            None,
+            True,
+        ),
+        (
+            'string',
+            {'integer', 'boolean'},
+            None,
+            False,
+        ),
+        (
+            'string',
+            {'integer', 'string', 'boolean'},
+            all,
+            True,
+        ),
+        (
+            'string',
+            {'integer', 'boolean'},
+            all,
+            False,
+        ),
+        (
+            ['string', 'array'],
+            {'integer', 'string', 'boolean'},
+            None,
+            True,
+        ),
+        (
+            ['string', 'array'],
+            {'integer', 'boolean'},
+            None,
+            False,
+        ),
+        (
+            ['string', 'array'],
+            {'integer', 'string', 'boolean', 'array'},
+            all,
+            True,
+        ),
+        (
+            ['string', 'array'],
+            {'integer', 'string', 'boolean'},
+            all,
+            False,
+        ),
+        (
+            ['string', 'array'],
+            {'integer', 'boolean'},
+            all,
+            False,
+        ),
+    ),
+)
+def test_compare_types_returns_whether_schema_type_matches_target_types(
+    schema_type, target_types, match, expected_result
+):
+    if match:
+        assert module.compare_types(schema_type, target_types, match) == expected_result
+    else:
+        assert module.compare_types(schema_type, target_types) == expected_result