bond-spy 0.1.0

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +27 -0
  7. data/README.rst +65 -0
  8. data/Rakefile +6 -0
  9. data/bin/bond_reconcile.py +385 -0
  10. data/bin/setup +5 -0
  11. data/bond.gemspec +36 -0
  12. data/lib/bond.rb +469 -0
  13. data/lib/bond/spec_helper.rb +32 -0
  14. data/lib/bond/targetable.rb +210 -0
  15. data/lib/bond/version.rb +3 -0
  16. data/spec/bond_spec.rb +158 -0
  17. data/spec/bond_targetable_spec.rb +202 -0
  18. data/spec/spec_helper.rb +2 -0
  19. data/spec/test_observations/.gitignore +2 -0
  20. data/spec/test_observations/bond_spec/Bond_with_agents_should_call_doers_before_returning_result.json +14 -0
  21. data/spec/test_observations/bond_spec/Bond_with_agents_should_call_the_function_passed_as_result_if_it_is_callable.json +23 -0
  22. data/spec/test_observations/bond_spec/Bond_with_agents_should_correctly_call_a_single_doer_if_filter_criteria_are_met.json +10 -0
  23. data/spec/test_observations/bond_spec/Bond_with_agents_should_correctly_call_multiple_doers.json +13 -0
  24. data/spec/test_observations/bond_spec/Bond_with_agents_should_not_call_doers_of_overriden_agents.json +8 -0
  25. data/spec/test_observations/bond_spec/Bond_with_agents_should_override_old_agents_with_newer_agents.json +0 -0
  26. data/spec/test_observations/bond_spec/Bond_with_agents_should_throw_an_exception_if_specified_by_agent.json +9 -0
  27. data/spec/test_observations/bond_spec/Bond_with_agents_should_throw_the_result_of_the_value_passed_to_exception_if_callable.json +10 -0
  28. data/spec/test_observations/bond_spec/Bond_with_agents_should_work_with_multiple_agents_for_different_spy_points.json +23 -0
  29. data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_override_old_agents_with_newer_agents_unless_theott8glo1xn.json +22 -0
  30. data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_combinations_of_filters.json +37 -0
  31. data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_function_filters.json +16 -0
  32. data/spec/test_observations/bond_spec/Bond_with_agents_with_filters_should_respect_single_key_value_filters_of_all_types.json +121 -0
  33. data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_nested_hashes_and_arrays_with_hash_sorting.json +31 -0
  34. data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_some_normal_arguments_with_a_spy_point_name.json +12 -0
  35. data/spec/test_observations/bond_spec/Bond_without_any_agents_should_correctly_log_some_normal_arguments_without_a_spy_point_name.json +10 -0
  36. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_continues_to_the_method_when_agent_result_continue_is_returned.json +10 -0
  37. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_continues_to_the_method_when_agent_result_none_is_returned.json +14 -0
  38. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_passes_through_blocks.json +10 -0
  39. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_returns_nil__and_mocks__when_an_agent_returns_nil.json +11 -0
  40. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_spies_private_methods.json +6 -0
  41. data/spec/test_observations/bond_targetable_spec/BondTargetable_correctly_spies_protected_methods.json +6 -0
  42. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_class_method.json +7 -0
  43. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_method_with_variabl19nhijeqoo.json +13 -0
  44. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_positional_a6qc3d4el92.json +33 -0
  45. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_positional_aott8glo1xn.json +20 -0
  46. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_mix_of_required_andbcgjq06had.json +17 -0
  47. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_a_normal_method.json +7 -0
  48. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_all_optional_keyword_arguments.json +10 -0
  49. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_argument_types_correctly_spies_on_variable_keyword_arguments.json +22 -0
  50. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_changes_the_spy_point_naj4gnwvcu8n.json +5 -0
  51. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_errors_when_mocking_is_r9j7wklng0z.json +6 -0
  52. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_ignores_excluded_keys.json +10 -0
  53. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_mocks_when_one_is_specified.json +10 -0
  54. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_spies_the_return_value_w19nhijeqoo.json +10 -0
  55. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_different_spy_point_parameters_correctly_spies_the_return_value_ww8esw1qdxc.json +10 -0
  56. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_modules_correctly_spies_on_included_module_methods.json +6 -0
  57. data/spec/test_observations/bond_targetable_spec/BondTargetable_with_modules_correctly_spies_on_module_methods.json +7 -0
  58. data/tutorials/binary_search_tree/bst.rb +120 -0
  59. data/tutorials/binary_search_tree/bst_spec.rb +82 -0
  60. data/tutorials/binary_search_tree/run_tests.sh +4 -0
  61. data/tutorials/binary_search_tree/test_observations/.gitignore +2 -0
  62. data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_add_nodes_to_the_BST_correctly__testing_with_Bond.json +20 -0
  63. data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_add_nodes_to_the_BST_correctly__testing_without_Bond.json +3 -0
  64. data/tutorials/binary_search_tree/test_observations/bst_spec/Node_should_correctly_delete_nodes_from_the_BST.json +29 -0
  65. data/tutorials/heat_watcher/heat_watcher.rb +107 -0
  66. data/tutorials/heat_watcher/heat_watcher_spec.rb +116 -0
  67. data/tutorials/heat_watcher/run_tests.sh +4 -0
  68. data/tutorials/heat_watcher/test_observations/.gitignore +2 -0
  69. data/tutorials/heat_watcher/test_observations/heat_watcher_spec/HeatWatcher_should_properly_report_critical_errors.json +142 -0
  70. data/tutorials/heat_watcher/test_observations/heat_watcher_spec/HeatWatcher_should_properly_report_warnings_and_switch_back_to_OK_status.json +132 -0
  71. metadata +211 -0
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_private_method",
4
+ "arg1": "value"
5
+ }
6
+ ]
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_protected_method",
4
+ "arg1": "value"
5
+ }
6
+ ]
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass.annotated_class_method",
4
+ "arg1": 1,
5
+ "arg2": 2
6
+ }
7
+ ]
@@ -0,0 +1,13 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_var_args",
4
+ "arg1": "value1",
5
+ "arg2": "value2"
6
+ },
7
+ {
8
+ "__spy_point__": "TestClass#annotated_method_var_args",
9
+ "anonymous_parameter0": "value4",
10
+ "arg1": "value1",
11
+ "arg2": "value2"
12
+ }
13
+ ]
@@ -0,0 +1,33 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_mixed_variable_params",
4
+ "arg1": "value1",
5
+ "arg_n1": "value_n1"
6
+ },
7
+ {
8
+ "__spy_point__": "TestClass#annotated_method_mixed_variable_params",
9
+ "arg1": "value1",
10
+ "arg_n1": "value_n1",
11
+ "arg_n2": "value_n2"
12
+ },
13
+ {
14
+ "__spy_point__": "TestClass#annotated_method_mixed_variable_params",
15
+ "anonymous_parameter0": "value3",
16
+ "arg1": "value1",
17
+ "arg_n1": "value_n1",
18
+ "arg_n2": "value_n2"
19
+ },
20
+ {
21
+ "__spy_point__": "TestClass#annotated_method_mixed_variable_params",
22
+ "anonymous_parameter0": "value3",
23
+ "arg1": "value1",
24
+ "arg_n1": "value_n1"
25
+ },
26
+ {
27
+ "__spy_point__": "TestClass#annotated_method_mixed_variable_params",
28
+ "anonymous_parameter0": "value3",
29
+ "arg1": "value1",
30
+ "arg_n1": "value_n1",
31
+ "arg_n3": "value_n3"
32
+ }
33
+ ]
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_mixed_params",
4
+ "arg1": "foo",
5
+ "arg2": "bar"
6
+ },
7
+ {
8
+ "__spy_point__": "TestClass#annotated_method_mixed_params",
9
+ "arg1": "foo",
10
+ "arg2": "bar",
11
+ "arg4": "new value4"
12
+ },
13
+ {
14
+ "__spy_point__": "TestClass#annotated_method_mixed_params",
15
+ "arg1": "foo",
16
+ "arg2": "bar",
17
+ "arg3": "new value3",
18
+ "arg4": "new value4"
19
+ }
20
+ ]
@@ -0,0 +1,17 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_kw_params_mixed",
4
+ "arg1": "value"
5
+ },
6
+ {
7
+ "__spy_point__": "TestClass#annotated_method_kw_params_mixed",
8
+ "arg1": "value",
9
+ "arg3": "new value"
10
+ },
11
+ {
12
+ "__spy_point__": "TestClass#annotated_method_kw_params_mixed",
13
+ "arg1": "value",
14
+ "arg2": "new value2",
15
+ "arg3": "new value3"
16
+ }
17
+ ]
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_standard_method",
4
+ "arg1": 1,
5
+ "arg2": 2
6
+ }
7
+ ]
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_kw_params_optional"
4
+ },
5
+ {
6
+ "__spy_point__": "TestClass#annotated_method_kw_params_optional",
7
+ "arg1": "value1",
8
+ "arg2": "value2"
9
+ }
10
+ ]
@@ -0,0 +1,22 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_variable_kw_args",
4
+ "arg1": "value1"
5
+ },
6
+ {
7
+ "__spy_point__": "TestClass#annotated_method_variable_kw_args",
8
+ "arg1": "value1",
9
+ "arg2": "value2"
10
+ },
11
+ {
12
+ "__spy_point__": "TestClass#annotated_method_variable_kw_args",
13
+ "arg1": "value1",
14
+ "arg3": "value3"
15
+ },
16
+ {
17
+ "__spy_point__": "TestClass#annotated_method_variable_kw_args",
18
+ "arg1": "value1",
19
+ "arg3": "value3",
20
+ "arg4": "value4"
21
+ }
22
+ ]
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestClass#annotated_method_single_exclude",
4
+ "arg2": "value2"
5
+ },
6
+ {
7
+ "__spy_point__": "TestClass#annotated_method_multiple_exclude",
8
+ "arg2": "value2"
9
+ }
10
+ ]
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "__spy_point__": "mock_required",
4
+ "arg1": 5
5
+ },
6
+ {
7
+ "__spy_point__": "return_value",
8
+ "return": "new return"
9
+ }
10
+ ]
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "__spy_point__": "spy_return",
4
+ "arg1": "arg_value"
5
+ },
6
+ {
7
+ "__spy_point__": "spy_return.result",
8
+ "result": "new return"
9
+ }
10
+ ]
@@ -0,0 +1,10 @@
1
+ [
2
+ {
3
+ "__spy_point__": "spy_return",
4
+ "arg1": "arg_value"
5
+ },
6
+ {
7
+ "__spy_point__": "spy_return.result",
8
+ "result": "return"
9
+ }
10
+ ]
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestModule#annotated_standard_method",
4
+ "arg1": "value"
5
+ }
6
+ ]
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "__spy_point__": "TestModule.annotated_class_method",
4
+ "arg1": "value1",
5
+ "arg2": "value2"
6
+ }
7
+ ]
@@ -0,0 +1,120 @@
1
+ # A tutorial on binary-search-trees, by Laurent Luce <http://www.laurentluce.com/>
2
+ # Code ported from Python to Ruby; original code from:
3
+ # http://www.laurentluce.com/posts/binary-search-tree-library-in-python/
4
+ #
5
+ # We use this code as the system-under-test
6
+
7
+
8
+ # Tree node: left and right child + data which can be any object
9
+ class Node
10
+
11
+ attr_accessor :left, :right, :data
12
+
13
+ # Node constructor
14
+ # @param data Node data object
15
+ def initialize(data)
16
+ @left = nil
17
+ @right = nil
18
+ @data = data
19
+ end
20
+
21
+ # Insert new node with data
22
+ # @param data node data object to insert
23
+ def insert(data)
24
+ if @data.nil?
25
+ @data = data
26
+ else
27
+ if data < @data
28
+ if @left.nil?
29
+ @left = Node.new(data)
30
+ else
31
+ @left.insert(data)
32
+ end
33
+ elsif data > @data
34
+ if @right.nil?
35
+ @right = Node.new(data)
36
+ else
37
+ @right.insert(data)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ # Lookup node containing data
44
+ # @param data node data object to look up
45
+ # @param parent node's parent
46
+ # @return node and node's parent if found or [nil, nil]
47
+ def lookup(data, parent=nil)
48
+ return [self, parent] if data == @data
49
+ if data < @data
50
+ return [nil, nil] if @left.nil?
51
+ @left.lookup(data, self)
52
+ else
53
+ return [nil, nil] if @right.nil?
54
+ @right.lookup(data, self)
55
+ end
56
+ end
57
+
58
+ # Delete node containing data
59
+ # @param data node's content to delete
60
+ def delete(data)
61
+ # get node containing data
62
+ node, parent = lookup(data)
63
+ return nil if node.nil?
64
+
65
+ children_count = node.children_count
66
+
67
+ if children_count == 0
68
+ # if node has no children, just remove it
69
+ if parent.nil?
70
+ @data = nil
71
+ else
72
+ if parent.left == node
73
+ parent.left = nil
74
+ else
75
+ parent.right = nil
76
+ end
77
+ end
78
+ elsif children_count == 1
79
+ # if node has 1 child, replace node with child
80
+ n = node.left.nil? ? node.right : node.left
81
+ if parent.nil?
82
+ @left = n.left
83
+ @right = n.right
84
+ @data = n.data
85
+ else
86
+ if parent.left == node
87
+ parent.left = n
88
+ else
89
+ parent.right = n
90
+ end
91
+ end
92
+ else
93
+ # Node has 2 children; find its successor
94
+ parent = node
95
+ successor = node.right
96
+ until successor.left.nil?
97
+ parent = successor
98
+ successor = successor.left
99
+ end
100
+ # replace node data by its successor data
101
+ node.data = successor.data
102
+ # fix successor's parent's child
103
+ if parent.left == successor
104
+ parent.left = successor.right
105
+ else
106
+ parent.right = successor.right
107
+ end
108
+ end
109
+ end
110
+
111
+ # Returns the number of children
112
+ def children_count
113
+ 0 if @left.nil? && @right.nil?
114
+ 1 if @left.nil? || @right.nil?
115
+ 2
116
+ end
117
+
118
+ end
119
+
120
+
@@ -0,0 +1,82 @@
1
+ # Tests for BST trees
2
+ require 'rspec'
3
+ require 'bond/spec_helper'
4
+ require './bst'
5
+
6
+ describe Node do
7
+ include_context :bond
8
+
9
+ let (:variant) { 1 } # Change this variant to 2 to simulate a change
10
+
11
+ it 'should add nodes to the BST correctly, testing without Bond' do
12
+ tree = create_tree_1
13
+
14
+ # Add expect().to here to verify the position in the tree
15
+ # of all the data points, in the order in which they were inserted
16
+ expect(tree.data).to eq(8)
17
+ expect(tree.right.data).to eq(12)
18
+ expect(tree.left.data).to eq(3)
19
+ expect(tree.left.right.data).to eq(4)
20
+ expect(tree.left.right.right.data).to eq(6)
21
+ end
22
+
23
+ it 'should add nodes to the BST correctly, testing with Bond' do
24
+ tree = create_tree_1
25
+
26
+ # Add here a call to bond.spy to spy the tree
27
+ bond.spy('test_add_1', tree: dump_tree(tree))
28
+ end
29
+
30
+ it 'should correctly delete nodes from the BST' do
31
+ tree = Node.new(8)
32
+ tree.insert(12)
33
+ tree.insert(3)
34
+ tree.insert(4)
35
+ tree.insert(6)
36
+
37
+ tree.delete(4)
38
+
39
+ # Add expect().to here to verify the position in the tree
40
+ # of all the data points, in the order in which they were inserted
41
+ expect(tree.data).to eq(8)
42
+ expect(tree.right.data).to eq(12)
43
+ expect(tree.left.data).to eq(3)
44
+ expect(tree.left.right.data).to eq(6)
45
+
46
+ # Add here a call to bond.spy to spy the tree
47
+ bond.spy('test_delete_1', tree: dump_tree(tree))
48
+
49
+ tree.delete(8)
50
+
51
+ # Add expect().to here to verify the position in the tree
52
+ # of all the data points, in the order in which they were inserted
53
+ expect(tree.data).to eq(12)
54
+ expect(tree.left.data).to eq(3)
55
+ expect(tree.left.right.data).to eq(6)
56
+
57
+ # Add here a call to bond.spy to spy the tree
58
+ bond.spy('test_delete_2', tree: dump_tree(tree))
59
+ end
60
+
61
+ # A helper function to convert a tree to a dictionary mirroring the tree contents
62
+ def dump_tree(node)
63
+ res = { data: node.data }
64
+ res[:left] = dump_tree(node.left) unless node.left.nil?
65
+ res[:right] = dump_tree(node.right) unless node.right.nil?
66
+ res
67
+ end
68
+
69
+ def create_tree_1
70
+ tree = Node.new(8)
71
+ tree.insert(12)
72
+ tree.insert(3)
73
+ puts variant
74
+ if variant == 1
75
+ tree.insert(4)
76
+ else
77
+ tree.insert(7)
78
+ end
79
+ tree.insert(6)
80
+ return tree
81
+ end
82
+ end