bond-spy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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