test_arguments.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import pytest
  2. from flexmock import flexmock
  3. from borgmatic.config import arguments as module
  4. def test_set_values_without_keys_bails():
  5. config = {'option': 'value'}
  6. module.set_values(config=config, keys=(), value=5)
  7. assert config == {'option': 'value'}
  8. def test_set_values_with_keys_adds_them_to_config():
  9. config = {'option': 'value'}
  10. module.set_values(config=config, keys=('foo', 'bar', 'baz'), value=5)
  11. assert config == {'option': 'value', 'foo': {'bar': {'baz': 5}}}
  12. def test_set_values_with_one_existing_key_adds_others_to_config():
  13. config = {'foo': {'other': 'value'}}
  14. module.set_values(config=config, keys=('foo', 'bar', 'baz'), value=5)
  15. assert config == {'foo': {'other': 'value', 'bar': {'baz': 5}}}
  16. def test_set_values_with_two_existing_keys_adds_others_to_config():
  17. config = {'foo': {'bar': {'other': 'value'}}}
  18. module.set_values(config=config, keys=('foo', 'bar', 'baz'), value=5)
  19. assert config == {'foo': {'bar': {'other': 'value', 'baz': 5}}}
  20. def test_set_values_with_list_index_key_adds_it_to_config():
  21. config = {'foo': {'bar': [{'option': 'value'}, {'other': 'thing'}]}}
  22. module.set_values(config=config, keys=('foo', 'bar[1]', 'baz'), value=5)
  23. assert config == {'foo': {'bar': [{'option': 'value'}, {'other': 'thing', 'baz': 5}]}}
  24. def test_set_values_with_list_index_key_out_of_range_raises():
  25. config = {'foo': {'bar': [{'option': 'value'}]}}
  26. with pytest.raises(ValueError):
  27. module.set_values(config=config, keys=('foo', 'bar[1]', 'baz'), value=5)
  28. def test_set_values_with_final_list_index_key_out_of_range_raises():
  29. config = {'foo': {'bar': [{'option': 'value'}]}}
  30. with pytest.raises(ValueError):
  31. module.set_values(config=config, keys=('foo', 'bar[1]'), value=5)
  32. def test_set_values_with_list_index_key_missing_list_and_out_of_range_raises():
  33. config = {'other': 'value'}
  34. with pytest.raises(ValueError):
  35. module.set_values(config=config, keys=('foo', 'bar[1]', 'baz'), value=5)
  36. def test_set_values_with_final_list_index_key_adds_it_to_config():
  37. config = {'foo': {'bar': [1, 2]}}
  38. module.set_values(config=config, keys=('foo', 'bar[1]'), value=5)
  39. assert config == {'foo': {'bar': [1, 5]}}
  40. def test_type_for_option_with_option_finds_type():
  41. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  42. lambda sub_schema: sub_schema['properties']
  43. )
  44. assert (
  45. module.type_for_option(
  46. schema={'type': 'object', 'properties': {'foo': {'type': 'integer'}}},
  47. option_keys=('foo',),
  48. )
  49. == 'integer'
  50. )
  51. def test_type_for_option_with_nested_option_finds_type():
  52. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  53. lambda sub_schema: sub_schema['properties']
  54. )
  55. assert (
  56. module.type_for_option(
  57. schema={
  58. 'type': 'object',
  59. 'properties': {
  60. 'foo': {'type': 'object', 'properties': {'bar': {'type': 'boolean'}}}
  61. },
  62. },
  63. option_keys=('foo', 'bar'),
  64. )
  65. == 'boolean'
  66. )
  67. def test_type_for_option_with_missing_nested_option_finds_nothing():
  68. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  69. lambda sub_schema: sub_schema['properties']
  70. )
  71. assert (
  72. module.type_for_option(
  73. schema={
  74. 'type': 'object',
  75. 'properties': {
  76. 'foo': {'type': 'object', 'properties': {'other': {'type': 'integer'}}}
  77. },
  78. },
  79. option_keys=('foo', 'bar'),
  80. )
  81. is None
  82. )
  83. def test_type_for_option_with_typeless_nested_option_finds_nothing():
  84. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  85. lambda sub_schema: sub_schema['properties']
  86. )
  87. assert (
  88. module.type_for_option(
  89. schema={
  90. 'type': 'object',
  91. 'properties': {'foo': {'type': 'object', 'properties': {'bar': {'example': 5}}}},
  92. },
  93. option_keys=('foo', 'bar'),
  94. )
  95. is None
  96. )
  97. def test_type_for_option_with_list_index_option_finds_type():
  98. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  99. lambda sub_schema: sub_schema['properties']
  100. )
  101. assert (
  102. module.type_for_option(
  103. schema={
  104. 'type': 'object',
  105. 'properties': {'foo': {'type': 'array', 'items': {'type': 'integer'}}},
  106. },
  107. option_keys=('foo[0]',),
  108. )
  109. == 'integer'
  110. )
  111. def test_type_for_option_with_nested_list_index_option_finds_type():
  112. flexmock(module.borgmatic.config.schema).should_receive('get_properties').replace_with(
  113. lambda sub_schema: sub_schema['properties']
  114. )
  115. assert (
  116. module.type_for_option(
  117. schema={
  118. 'type': 'object',
  119. 'properties': {
  120. 'foo': {
  121. 'type': 'array',
  122. 'items': {'type': 'object', 'properties': {'bar': {'type': 'integer'}}},
  123. }
  124. },
  125. },
  126. option_keys=('foo[0]', 'bar'),
  127. )
  128. == 'integer'
  129. )
  130. def test_prepare_arguments_for_config_converts_arguments_to_keys():
  131. assert module.prepare_arguments_for_config(
  132. global_arguments=flexmock(**{'my_option.sub_option': 'value1', 'other_option': 'value2'}),
  133. schema={
  134. 'type': 'object',
  135. 'properties': {
  136. 'my_option': {'type': 'object', 'properties': {'sub_option': {'type': 'string'}}},
  137. 'other_option': {'type': 'string'},
  138. },
  139. },
  140. ) == (
  141. (('my_option', 'sub_option'), 'value1'),
  142. (('other_option',), 'value2'),
  143. )
  144. def test_prepare_arguments_for_config_skips_option_with_none_value():
  145. assert module.prepare_arguments_for_config(
  146. global_arguments=flexmock(**{'my_option.sub_option': None, 'other_option': 'value2'}),
  147. schema={
  148. 'type': 'object',
  149. 'properties': {
  150. 'my_option': {'type': 'object', 'properties': {'sub_option': {'type': 'string'}}},
  151. 'other_option': {'type': 'string'},
  152. },
  153. },
  154. ) == ((('other_option',), 'value2'),)
  155. def test_prepare_arguments_for_config_skips_option_missing_from_schema():
  156. assert module.prepare_arguments_for_config(
  157. global_arguments=flexmock(**{'my_option.sub_option': 'value1', 'other_option': 'value2'}),
  158. schema={
  159. 'type': 'object',
  160. 'properties': {
  161. 'my_option': {'type': 'object'},
  162. 'other_option': {'type': 'string'},
  163. },
  164. },
  165. ) == ((('other_option',), 'value2'),)
  166. def test_apply_arguments_to_config_does_not_raise():
  167. flexmock(module).should_receive('prepare_arguments_for_config').and_return(
  168. (
  169. (('foo', 'bar'), 'baz'),
  170. (('one', 'two'), 'three'),
  171. )
  172. )
  173. flexmock(module).should_receive('set_values')
  174. module.apply_arguments_to_config(config={}, schema={}, arguments={'global': flexmock()})