delfos 0.0.1.pre.beta

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,38 @@
1
+ # frozen_string_literal: true
2
+ require "delfos"
3
+ require "json"
4
+
5
+ module Delfos
6
+ module Neo4j
7
+ module QueryExecution
8
+ class << self
9
+ def execute(query, url=nil)
10
+ result = JSON.parse response_for(query)
11
+ result["results"].first["data"].map{|r| r["row"]}
12
+ end
13
+
14
+ private
15
+
16
+ def response_for(query)
17
+ body = <<-BODY.gsub(/^\s+/, "").chomp
18
+ {"statements": [ { "statement": #{query.inspect} }]}
19
+ BODY
20
+ url = "http://neo4j:password@localhost:7474/db/data/transaction/commit"
21
+
22
+ command = "curl #{headers} --data-ascii '#{body}' #{url} 2> /dev/null"
23
+
24
+ `#{command}`
25
+ end
26
+
27
+ def headers
28
+ <<-HEADERS.chomp
29
+ -H "User-Agent: delfos" -H "Accept: application/json; charset=UTF-8" -H "Content-Type: application/json"
30
+ HEADERS
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+ module Delfos
3
+ class Patching
4
+ class << self
5
+ def perform(klass, name, private_methods, class_method:)
6
+ new(klass, name, private_methods, class_method).setup
7
+ end
8
+
9
+ def added_methods
10
+ @added_methods ||= {}
11
+ end
12
+
13
+ def method_definition_for(klass, key)
14
+ # Find method definitions defined in klass or its ancestors
15
+ super_klass = klass.ancestors.detect do |k|
16
+ added_methods[k.to_s]
17
+ end
18
+
19
+ klass_hash = added_methods[super_klass.to_s] || {}
20
+ klass_hash[key]
21
+ end
22
+ end
23
+
24
+ attr_reader :klass, :name, :private_methods, :class_method
25
+
26
+ def initialize(klass, name, private_methods, class_method)
27
+ @klass = klass
28
+ @name = name
29
+ @private_methods = private_methods
30
+ @class_method = class_method
31
+ end
32
+
33
+ # Redefine the method (only once) at runtime to enabling logging to Neo4j
34
+ def setup
35
+ return if ensure_method_recorded!
36
+ original = original_method
37
+ class_method = class_method()
38
+ performer = method(:perform_call)
39
+
40
+ method_defining_method.call(name) do |*args, **keyword_args, &block|
41
+ MethodLogging.log(self, args, keyword_args, block, class_method, caller.dup, binding.dup, original)
42
+
43
+ method_to_call = class_method ? original : original.bind(self)
44
+ result = performer.call(method_to_call, args, keyword_args, block)
45
+ Delfos::ExecutionChain.pop
46
+ result
47
+ end
48
+ end
49
+
50
+
51
+ private
52
+
53
+ def perform_call(method_to_call, args, keyword_args, block)
54
+ if keyword_args.empty?
55
+ method_to_call.call(*args, &block)
56
+ else
57
+ method_to_call.call(*args, **keyword_args, &block)
58
+ end
59
+ end
60
+
61
+ def original_method
62
+ @original_method ||= class_method ? klass.singleton_method(name) : klass.instance_method(name)
63
+ end
64
+
65
+ def method_defining_method
66
+ class_method ? klass.method(:define_singleton_method) : klass.method(:define_method)
67
+ end
68
+
69
+ def ensure_method_recorded!
70
+ return true if bail?
71
+
72
+ self.class.added_methods[klass.to_s] ||= {}
73
+ self.class.added_methods[klass.to_s][key] = original_method.source_location
74
+
75
+ false
76
+ end
77
+
78
+ def bail?
79
+ method_has_been_added? || private_method? || exclude?
80
+ end
81
+
82
+ def method_has_been_added?
83
+ return false unless self.class.added_methods[self]
84
+ return false unless self.class.added_methods[self][klass]
85
+
86
+ self.class.added_methods[klass][key]
87
+ end
88
+
89
+ def private_method?
90
+ private_methods.include?(name.to_sym)
91
+ end
92
+
93
+ def exclude?
94
+ ::Delfos::MethodLogging.exclude_from_logging?(original_method)
95
+ end
96
+
97
+ def key
98
+ "#{type}_#{name}"
99
+ end
100
+
101
+ def type
102
+ class_method ? "ClassMethod" : "InstanceMethod"
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,44 @@
1
+ # This existence of these `Unstubbing` modules are an unfortunate side effect of trying to
2
+ # test something that redefines methods. In order to not call the logging
3
+ # defined in `Delfos::Patching#setup` multiple times we have to keep track of
4
+ # and remove the method definitions and replace with the original definition
5
+ # (or as close to the original as possible).
6
+ #
7
+ # If there is a better way to test Delfos::Patching without doing this then
8
+ # please suggest or replace with a cleaner alternative
9
+ module Unstubbing
10
+ module ClassMethods
11
+ def add_instance_to_unstub!(object)
12
+ instances_to_unstub.push(object)
13
+ end
14
+
15
+ def unstub_all!
16
+ instances_to_unstub.each(&:unstub!)
17
+ end
18
+
19
+ private
20
+
21
+ def instances_to_unstub
22
+ @instances_to_unstub ||= []
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+ def initialize(*args)
28
+ super(*args)
29
+ self.class.add_instance_to_unstub!(self) unless bail?
30
+ end
31
+
32
+ # This method is the inverse of `Delfos::Patching#setup`
33
+ def unstub!
34
+ original = original_method
35
+ class_method = class_method()
36
+ performer = method(:perform_call)
37
+
38
+ method_defining_method.call(name) do |*args, **keyword_args, &block|
39
+ method_to_call = class_method ? original : original.bind(self)
40
+ performer.call(method_to_call, args, keyword_args, block)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ require_relative "patching"
3
+
4
+ class BasicObject
5
+ def self.method_added(name)
6
+ return if name == __method__
7
+
8
+ ::Delfos::Patching.perform(self, name, private_instance_methods, class_method: false)
9
+ end
10
+
11
+ def self.singleton_method_added(name)
12
+ return if name == __method__
13
+
14
+ ::Delfos::Patching.perform(self, name, private_methods, class_method: true)
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ class BasicObject
3
+ def self.method_added(*_args)
4
+ nil
5
+ end
6
+
7
+ def self.singleton_method_added(*_args)
8
+ nil
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module Delfos
3
+ VERSION = "0.0.1-beta"
4
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delfos
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre.beta
5
+ platform: ruby
6
+ authors:
7
+ - Mark Burns
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: binding_of_caller
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: what_weve_got_here_is_an_error_to_communicate
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: awesome_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 11.1.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 11.1.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.4.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.4.0
111
+ description: Just because
112
+ email:
113
+ - markburns@notonthehighstreet.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - lib/delfos.rb
119
+ - lib/delfos/common_path.rb
120
+ - lib/delfos/distance/calculation.rb
121
+ - lib/delfos/distance/relation.rb
122
+ - lib/delfos/execution_chain.rb
123
+ - lib/delfos/method_logging.rb
124
+ - lib/delfos/method_logging/args.rb
125
+ - lib/delfos/method_logging/code_location.rb
126
+ - lib/delfos/method_logging/klass_determination.rb
127
+ - lib/delfos/neo4j/distance_update.rb
128
+ - lib/delfos/neo4j/execution_persistence.rb
129
+ - lib/delfos/neo4j/informer.rb
130
+ - lib/delfos/neo4j/query_execution.rb
131
+ - lib/delfos/patching.rb
132
+ - lib/delfos/patching_unstubbing_spec_helper.rb
133
+ - lib/delfos/perform_patching.rb
134
+ - lib/delfos/remove_patching.rb
135
+ - lib/delfos/version.rb
136
+ homepage: https://github.com/markburns/delfos
137
+ licenses:
138
+ - MIT
139
+ metadata:
140
+ allowed_push_host: https://rubygems.org
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">"
153
+ - !ruby/object:Gem::Version
154
+ version: 1.3.1
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.5.1
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Record every method call in an application
161
+ test_files: []