paramify 0.1.4__py3-none-any.whl

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.
@@ -0,0 +1,64 @@
1
+ import unittest
2
+ from paramify.paramify import Paramify
3
+
4
+ class TestParamifyDynamicSetters(unittest.TestCase):
5
+
6
+ def setUp(self):
7
+ # Sample configuration for dynamic setter tests
8
+ self.valid_dict_config = {
9
+ "parameters": [
10
+ {"name": "param1", "type": "bool", "default": True},
11
+ {"name": "param2", "type": "int", "default": 42}
12
+ ]
13
+ }
14
+
15
+ def test_dynamic_setter_creation(self):
16
+ """Test that dynamic setters are created for each parameter."""
17
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
18
+
19
+ # Verify that setter methods exist
20
+ self.assertTrue(hasattr(paramify, "set_param1"))
21
+ self.assertTrue(hasattr(paramify, "set_param2"))
22
+
23
+ def test_dynamic_setter_updates_value(self):
24
+ """Test that dynamic setters correctly update parameter values."""
25
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
26
+
27
+ # Use dynamic setters to update values
28
+ paramify.set_param1(False)
29
+ paramify.set_param2(100)
30
+
31
+ # Verify that values are updated
32
+ self.assertFalse(paramify.get_parameters()["param1"])
33
+ self.assertEqual(paramify.get_parameters()["param2"], 100)
34
+
35
+ def test_dynamic_setter_validation(self):
36
+ """Test that dynamic setters validate values before updating."""
37
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
38
+
39
+ # Attempt to set invalid values and verify exceptions
40
+ with self.assertRaises(TypeError):
41
+ paramify.set_param1("not_a_bool") # Invalid bool value
42
+
43
+ with self.assertRaises(TypeError):
44
+ paramify.set_param2("not_an_int") # Invalid int value
45
+
46
+ def test_dynamic_setter_callbacks(self):
47
+ """Test that dynamic setters invoke callback methods if defined."""
48
+ class CallbackTestParamify(Paramify):
49
+ def __init__(self, *args, **kwargs):
50
+ super().__init__(*args, **kwargs)
51
+ self.callback_triggered = False
52
+
53
+ def on_param1_set(self, value):
54
+ self.callback_triggered = True
55
+
56
+ # Initialize the Paramify subclass with a callback
57
+ paramify = CallbackTestParamify(self.valid_dict_config, enable_cli=False)
58
+
59
+ # Update param1 and verify the callback is triggered
60
+ paramify.set_param1(False)
61
+ self.assertTrue(paramify.callback_triggered)
62
+
63
+ if __name__ == "__main__":
64
+ unittest.main()
@@ -0,0 +1,88 @@
1
+ import unittest
2
+ import json
3
+ import os
4
+ from paramify.paramify import Paramify
5
+ from tempfile import NamedTemporaryFile
6
+ from ruamel.yaml import scanner
7
+
8
+
9
+ class TestParamifyInitialization(unittest.TestCase):
10
+
11
+ def setUp(self):
12
+ # Prepare sample configurations for testing
13
+ self.valid_dict_config = {
14
+ "parameters": [
15
+ {"name": "param1", "type": "bool", "default": True},
16
+ {"name": "param2", "type": "int", "default": 42}
17
+ ]
18
+ }
19
+
20
+ self.valid_json_file = NamedTemporaryFile(suffix=".json", mode='w', delete=False)
21
+ json.dump(self.valid_dict_config, self.valid_json_file)
22
+ self.valid_json_file.close()
23
+
24
+ self.invalid_json_file = NamedTemporaryFile(suffix=".json", mode='w', delete=False)
25
+ self.invalid_json_file.write("invalid-json")
26
+ self.invalid_json_file.close()
27
+
28
+ self.valid_yaml_file = NamedTemporaryFile(suffix=".yaml", mode='w', delete=False)
29
+ self.valid_yaml_file.write("parameters:\n - name: param1\n type: bool\n default: true\n - name: param2\n type: int\n default: 42\n")
30
+ self.valid_yaml_file.close()
31
+
32
+ self.invalid_yaml_file = NamedTemporaryFile(suffix=".yaml", mode='w', delete=False)
33
+ self.invalid_yaml_file.write("invalid: yaml: content")
34
+ self.invalid_yaml_file.close()
35
+
36
+ def tearDown(self):
37
+ # Clean up temporary files
38
+ os.unlink(self.valid_json_file.name)
39
+ os.unlink(self.invalid_json_file.name)
40
+ os.unlink(self.valid_yaml_file.name)
41
+ os.unlink(self.invalid_yaml_file.name)
42
+
43
+ def test_valid_dict_configuration(self):
44
+ """Test initialization with a valid dictionary configuration."""
45
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
46
+ self.assertEqual(paramify.get_parameters()["param1"], True)
47
+ self.assertEqual(paramify.get_parameters()["param2"], 42)
48
+
49
+ def test_valid_json_file_configuration(self):
50
+ """Test initialization with a valid JSON file."""
51
+ paramify = Paramify(self.valid_json_file.name, enable_cli=False)
52
+ self.assertEqual(paramify.get_parameters()["param1"], True)
53
+ self.assertEqual(paramify.get_parameters()["param2"], 42)
54
+
55
+ def test_valid_yaml_file_configuration(self):
56
+ """Test initialization with a valid YAML file."""
57
+ paramify = Paramify(self.valid_yaml_file.name, enable_cli=False)
58
+ self.assertEqual(paramify.get_parameters()["param1"], True)
59
+ self.assertEqual(paramify.get_parameters()["param2"], 42)
60
+
61
+ def test_invalid_file_format(self):
62
+ """Test that an invalid file format raises a ValueError."""
63
+ with self.assertRaises(ValueError):
64
+ Paramify("invalid_file.txt")
65
+
66
+ def test_invalid_json_configuration(self):
67
+ """Test that an invalid JSON file raises a ValueError."""
68
+ with self.assertRaises(ValueError):
69
+ Paramify(self.invalid_json_file.name)
70
+
71
+ def test_invalid_yaml_configuration(self):
72
+ """Test that an invalid YAML file raises a ValueError."""
73
+ with self.assertRaises(scanner.ScannerError):
74
+ Paramify(self.invalid_yaml_file.name, enable_cli=False)
75
+
76
+ def test_missing_parameters_key(self):
77
+ """Test that a configuration without a 'parameters' key raises a ValueError."""
78
+ invalid_config = {"settings": []} # Missing 'parameters' key
79
+ with self.assertRaises(ValueError):
80
+ Paramify(invalid_config)
81
+
82
+ def test_empty_configuration(self):
83
+ """Test that an empty configuration raises a ValueError."""
84
+ with self.assertRaises(ValueError):
85
+ Paramify({})
86
+
87
+ if __name__ == "__main__":
88
+ unittest.main()
@@ -0,0 +1,61 @@
1
+ import unittest
2
+ from paramify.paramify import Paramify
3
+
4
+ class TestParamifyMiscellaneous(unittest.TestCase):
5
+
6
+ def setUp(self):
7
+ # Sample configuration for testing miscellaneous methods
8
+ self.valid_dict_config = {
9
+ "parameters": [
10
+ {"name": "param1", "type": "bool", "default": True, "label": "Enable Feature"},
11
+ {"name": "param2", "type": "int", "default": 42, "label": "Maximum Value"}
12
+ ],
13
+ "name": "TestApp"
14
+ }
15
+
16
+ def test_get_parameters(self):
17
+ """Test that get_parameters returns the current parameter values as a dictionary."""
18
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
19
+ parameters = paramify.get_parameters()
20
+
21
+ # Verify the returned dictionary matches the expected values
22
+ expected_parameters = {
23
+ "param1": True,
24
+ "param2": 42
25
+ }
26
+ self.assertEqual(parameters, expected_parameters)
27
+
28
+ def test_update_non_existent_parameter(self):
29
+ """Test that updating a non-existent parameter raises an AttributeError."""
30
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
31
+
32
+ # Attempt to set a parameter that doesn't exist
33
+ with self.assertRaises(AttributeError):
34
+ paramify.set_param3("value") # param3 is not defined
35
+
36
+ def test_invalid_type_update(self):
37
+ """Test that updating a parameter with an invalid type raises TypeError."""
38
+ paramify = Paramify(self.valid_dict_config, enable_cli=False)
39
+
40
+ # Attempt to set an invalid type
41
+ with self.assertRaises(TypeError):
42
+ paramify.set_param1("not_a_bool") # param1 expects a bool
43
+
44
+ with self.assertRaises(TypeError):
45
+ paramify.set_param2("not_an_int") # param2 expects an int
46
+
47
+ def test_out_of_range_update(self):
48
+ """Test that updating a parameter with a value out of acceptable range raises an error."""
49
+ class RangeValidatingParamify(Paramify):
50
+ def on_param2_set(self, value):
51
+ if not (0 <= value <= 100):
52
+ raise ValueError("param2 must be between 0 and 100")
53
+
54
+ paramify = RangeValidatingParamify(self.valid_dict_config, enable_cli=False)
55
+
56
+ # Attempt to set a value out of range
57
+ with self.assertRaises(ValueError):
58
+ paramify.set_param2(150) # Out of range for param2
59
+
60
+ if __name__ == "__main__":
61
+ unittest.main()
@@ -0,0 +1,95 @@
1
+ import unittest
2
+ from paramify.paramify import Paramify
3
+
4
+ class TestParamifyPerformanceEdgeCases(unittest.TestCase):
5
+
6
+ def setUp(self):
7
+ # Sample configuration for edge case and performance testing
8
+ self.small_config = {
9
+ "parameters": [
10
+ {"name": "param1", "type": "bool", "default": True, "label": "Enable Feature"},
11
+ {"name": "param2", "type": "int", "default": 42, "label": "Maximum Value"}
12
+ ],
13
+ "name": "TestApp"
14
+ }
15
+
16
+ self.large_config = {
17
+ "parameters": [
18
+ {"name": f"param{i}", "type": "int", "default": i} for i in range(1000)
19
+ ],
20
+ "name": "LargeTestApp"
21
+ }
22
+
23
+ def test_large_configuration(self):
24
+ """Test initialization and operations with a large configuration."""
25
+ paramify = Paramify(self.large_config, enable_cli=False)
26
+
27
+ # Verify that all parameters are initialized correctly
28
+ parameters = paramify.get_parameters()
29
+ self.assertEqual(len(parameters), 1000)
30
+ for i in range(1000):
31
+ self.assertEqual(parameters[f"param{i}"], i)
32
+
33
+ def test_edge_case_parameter_names(self):
34
+ """Test handling of edge case parameter names."""
35
+ edge_case_config = {
36
+ "parameters": [
37
+ {"name": "param_with_@_symbol", "type": "str", "default": "value"},
38
+ {"name": "param_with_a_really_really_long_name_exceeding_normal_limits", "type": "int", "default": 999},
39
+ {"name": "param_with spaces", "type": "bool", "default": True}
40
+ ]
41
+ }
42
+
43
+ paramify = Paramify(edge_case_config, enable_cli=False)
44
+ parameters = paramify.get_parameters()
45
+
46
+ # Verify that all edge case parameters are handled correctly
47
+ self.assertEqual(parameters["param_with_@_symbol"], "value")
48
+ self.assertEqual(parameters["param_with_a_really_really_long_name_exceeding_normal_limits"], 999)
49
+ self.assertTrue(parameters["param_with spaces"])
50
+
51
+ def test_empty_configuration(self):
52
+ """Test initialization with an empty configuration."""
53
+ with self.assertRaises(ValueError):
54
+ Paramify({}, enable_cli=False)
55
+
56
+ def test_conflicting_updates(self):
57
+ """Test behavior when conflicting updates are made via setters and CLI arguments."""
58
+ class ConflictParamify(Paramify):
59
+ def on_param2_set(self, value):
60
+ self.param2_updated_via_setter = value
61
+
62
+ config = {
63
+ "parameters": [
64
+ {"name": "param1", "type": "bool", "default": True},
65
+ {"name": "param2", "type": "int", "default": 42}
66
+ ]
67
+ }
68
+
69
+ # Simulate CLI arguments
70
+ with unittest.mock.patch('sys.argv', ['execution.py', '--param2', '100']):
71
+ paramify = ConflictParamify(config, enable_cli=True)
72
+
73
+ # Update via setter after CLI parsing
74
+ paramify.set_param2(200)
75
+
76
+ # Verify the final value
77
+ self.assertEqual(paramify.get_parameters()["param2"], 200)
78
+ self.assertEqual(paramify.param2_updated_via_setter, 200)
79
+
80
+ def test_stress_dynamic_updates(self):
81
+ """Stress test for dynamically updating a large number of parameters."""
82
+ paramify = Paramify(self.large_config, enable_cli=False)
83
+
84
+ # Dynamically update all parameters
85
+ for i in range(1000):
86
+ setter = getattr(paramify, f"set_param{i}")
87
+ setter(i * 2) # Double each parameter's value
88
+
89
+ # Verify the updates
90
+ parameters = paramify.get_parameters()
91
+ for i in range(1000):
92
+ self.assertEqual(parameters[f"param{i}"], i * 2)
93
+
94
+ if __name__ == "__main__":
95
+ unittest.main()
@@ -0,0 +1,80 @@
1
+ import unittest
2
+ import json
3
+ import os
4
+ from tempfile import NamedTemporaryFile
5
+ from paramify.paramify import Paramify
6
+ from ruamel.yaml import YAML
7
+
8
+ class TestParamifyPersistence(unittest.TestCase):
9
+
10
+ def setUp(self):
11
+ # Prepare a valid JSON configuration file
12
+ self.valid_json_config = {
13
+ "parameters": [
14
+ {"name": "param1", "type": "bool", "default": True},
15
+ {"name": "param2", "type": "int", "default": 42}
16
+ ]
17
+ }
18
+
19
+ self.valid_json_file = NamedTemporaryFile(suffix=".json", mode="w", delete=False)
20
+ json.dump(self.valid_json_config, self.valid_json_file)
21
+ self.valid_json_file.close()
22
+
23
+ # Prepare a valid YAML configuration file
24
+ self.valid_yaml_file = NamedTemporaryFile(suffix=".yaml", mode="w", delete=False)
25
+ yaml = YAML()
26
+ yaml.dump(self.valid_json_config, self.valid_yaml_file)
27
+ self.valid_yaml_file.close()
28
+
29
+ def tearDown(self):
30
+ # Clean up temporary files
31
+ os.unlink(self.valid_json_file.name)
32
+ os.unlink(self.valid_yaml_file.name)
33
+
34
+ def test_json_persistence(self):
35
+ """Test that changes to parameters are persisted to a JSON file."""
36
+ paramify = Paramify(self.valid_json_file.name, enable_cli=False)
37
+
38
+ # Update parameters
39
+ paramify.set_param1(False)
40
+ paramify.set_param2(100)
41
+
42
+ # Reload the file and verify changes
43
+ with open(self.valid_json_file.name, "r") as f:
44
+ updated_config = json.load(f)
45
+
46
+ updated_params = {p["name"]: p["default"] for p in updated_config["parameters"]}
47
+ self.assertFalse(updated_params["param1"])
48
+ self.assertEqual(updated_params["param2"], 100)
49
+
50
+ def test_yaml_persistence(self):
51
+ """Test that changes to parameters are persisted to a YAML file."""
52
+ paramify = Paramify(self.valid_yaml_file.name, enable_cli=False)
53
+
54
+ # Update parameters
55
+ paramify.set_param1(False)
56
+ paramify.set_param2(100)
57
+
58
+ # Reload the file and verify changes
59
+ yaml = YAML()
60
+ with open(self.valid_yaml_file.name, "r") as f:
61
+ updated_config = yaml.load(f)
62
+
63
+ updated_params = {p["name"]: p["default"] for p in updated_config["parameters"]}
64
+ self.assertFalse(updated_params["param1"])
65
+ self.assertEqual(updated_params["param2"], 100)
66
+
67
+ def test_no_persistence_for_dict_config(self):
68
+ """Test that changes are not persisted when initialized with a dictionary configuration."""
69
+ paramify = Paramify(self.valid_json_config, enable_cli=False)
70
+
71
+ # Update parameters
72
+ paramify.set_param1(False)
73
+ paramify.set_param2(100)
74
+
75
+ # Verify the original configuration is unchanged
76
+ self.assertTrue(self.valid_json_config["parameters"][0]["default"])
77
+ self.assertEqual(self.valid_json_config["parameters"][1]["default"], 42)
78
+
79
+ if __name__ == "__main__":
80
+ unittest.main()
@@ -0,0 +1,61 @@
1
+ import unittest
2
+ from paramify.paramify import Paramify
3
+ from tempfile import NamedTemporaryFile
4
+
5
+ class TestParamifyValidation(unittest.TestCase):
6
+
7
+ def setUp(self):
8
+ # Prepare sample configurations for testing
9
+ self.valid_dict_config = {
10
+ "parameters": [
11
+ {"name": "param1", "type": "bool", "default": True},
12
+ {"name": "param2", "type": "int", "default": 42}
13
+ ]
14
+ }
15
+
16
+ def tearDown(self):
17
+ pass
18
+
19
+ def test_valid_dict_configuration(self):
20
+ """Test initialization with a valid dictionary configuration."""
21
+ paramify = Paramify(self.valid_dict_config, enable_cli=False) # Disable CLI parsing
22
+ self.assertEqual(paramify.get_parameters()["param1"], True)
23
+ self.assertEqual(paramify.get_parameters()["param2"], 42)
24
+
25
+ def test_type_enforcement(self):
26
+ """Test that parameter types are enforced during initialization."""
27
+ invalid_config = {
28
+ "parameters": [
29
+ {"name": "param1", "type": "bool", "default": "not_a_bool"}, # Invalid bool
30
+ {"name": "param2", "type": "int", "default": "not_an_int"} # Invalid int
31
+ ]
32
+ }
33
+
34
+ with self.assertRaises(ValueError):
35
+ Paramify(invalid_config, enable_cli=False)
36
+
37
+ def test_missing_default(self):
38
+ """Test that parameters without a default are initialized as None."""
39
+ config = {
40
+ "parameters": [
41
+ {"name": "param1", "type": "str"}, # No default value
42
+ {"name": "param2", "type": "int", "default": 10}
43
+ ]
44
+ }
45
+ paramify = Paramify(config, enable_cli=False)
46
+ self.assertIsNone(paramify.get_parameters()["param1"])
47
+ self.assertEqual(paramify.get_parameters()["param2"], 10)
48
+
49
+
50
+ def test_optional_parameters(self):
51
+ """Test that parameters without default values are treated as optional."""
52
+ config = {
53
+ "parameters": [
54
+ {"name": "param1", "type": "float"} # No default
55
+ ]
56
+ }
57
+ paramify = Paramify(config, enable_cli=False)
58
+ self.assertIsNone(paramify.get_parameters()["param1"])
59
+
60
+ if __name__ == "__main__":
61
+ unittest.main()