police-vminfo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source :rubygems
2
+
3
+ group :development do
4
+ gem 'bundler', '>= 1.1.0'
5
+ gem 'jeweler', '>= 1.8.3'
6
+ gem 'minitest', '>= 2.11.2'
7
+ gem 'rdoc', '>= 3.12'
8
+ gem 'simplecov', '>= 0.6.1'
9
+ gem 'yard', '>= 0.7'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,31 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.8.3)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rdoc
10
+ json (1.6.6)
11
+ minitest (2.11.4)
12
+ multi_json (1.2.0)
13
+ rake (0.9.2.2)
14
+ rdoc (3.12)
15
+ json (~> 1.4)
16
+ simplecov (0.6.1)
17
+ multi_json (~> 1.0)
18
+ simplecov-html (~> 0.5.3)
19
+ simplecov-html (0.5.3)
20
+ yard (0.7.5)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ bundler (>= 1.1.0)
27
+ jeweler (>= 1.8.3)
28
+ minitest (>= 2.11.2)
29
+ rdoc (>= 3.12)
30
+ simplecov (>= 0.6.1)
31
+ yard (>= 0.7)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Victor Costan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,17 @@
1
+ # police-vminfo
2
+
3
+ Collects information about the internals of the running Ruby VM.
4
+
5
+ This is useful for applications that want to re-implement standard library
6
+ objects such as String, or track their usage, e.g. for data flow taint tracking.
7
+ The code here can be used to ensure that an implementation fully covers an
8
+ object's methods.
9
+
10
+ Right now, this gem collects the Ruby exploration code used to build
11
+ police-dataflow.
12
+
13
+
14
+ ## Copyright
15
+
16
+ Copyright (c) 2012 Massachusetts Institute of Technology. See LICENSE.txt for
17
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "police-vminfo"
18
+ gem.homepage = "http://github.com/pwnall/police-vminfo"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Information about the Ruby VM internals.}
21
+ gem.description = %Q{Collects information about the Ruby VM implementation details.}
22
+ gem.email = "victor@costan.us"
23
+ gem.authors = ["Victor Costan"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'yard'
38
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,2 @@
1
+ # Allow require 'police-vminfo' instead of 'police/vminfo'
2
+ require 'police/vminfo'
@@ -0,0 +1,3 @@
1
+ require 'police/vminfo/objects.rb'
2
+ require 'police/vminfo/paths.rb'
3
+ require 'police/vminfo/signature.rb'
@@ -0,0 +1,164 @@
1
+ module Police
2
+
3
+ module VmInfo
4
+ # All loaded Ruby modules, obtained by walking the constants graph.
5
+ #
6
+ # @return [Array<Module>] the Ruby modules that could be discovered by
7
+ # searching the constants graph; this should include everything except for
8
+ # anonymous (not assigned to constants) classes
9
+ def self.named_modules
10
+ # NOTE: this is a Set, but we don't want to load the module.
11
+ explored = { Object => true }
12
+ left = [Object]
13
+ until left.empty?
14
+ namespace = left.pop
15
+ namespace.constants.each do |const_name|
16
+ begin
17
+ const = if namespace.const_defined? const_name
18
+ namespace.const_get const_name
19
+ else
20
+ namespace.const_missing const_name
21
+ end
22
+ rescue LoadError, NameError
23
+ # Delayed loading failure.
24
+ next
25
+ end
26
+ next if explored[const] || !const.kind_of?(Module)
27
+ explored[const] = true
28
+ left.push const
29
+ end
30
+ end
31
+ explored.keys.sort_by!(&:name).freeze
32
+ end
33
+
34
+ # All loaded Ruby classes, obtained by walking the constants graph.
35
+ #
36
+ # Note that all classes are modules, so this is a subset of named_modules.
37
+ #
38
+ # @return [Array<Module>] the Ruby classes that could be discovered by
39
+ # searching the constants graph; this should include everything except for
40
+ # anonymous (not assigned to constants) classes
41
+ def self.named_classes
42
+ named_modules.select { |m| m.kind_of? Class }
43
+ end
44
+
45
+ # All loaded Ruby modules, obtained by querying ObjectSpace.
46
+ #
47
+ # Querying ObjectSpace can be painfully slow, especially on non-MRI VMs.
48
+ #
49
+ # @return [Array<Module>] all the Ruby modules
50
+ def self.all_modules
51
+ ObjectSpace.each_object(Module).to_a
52
+ end
53
+
54
+ # All loaded Ruby classes, obtained by querying ObjectSpace.
55
+ #
56
+ # Querying ObjectSpace can be painfully slow, especially on non-MRI VMs. Note
57
+ # that all classes are modules, so this is a subset of all_modules.
58
+ #
59
+ # @return [Array<Classes>] all the Ruby classes
60
+ def self.all_classes
61
+ ObjectSpace.each_object(Class).to_a
62
+ end
63
+
64
+ # The modules making up the Ruby VM implementation.
65
+ #
66
+ # @return [Array<Module>] the modules that are present in a vanilla Ruby
67
+ # environment
68
+ def self.core_modules
69
+ return @core_modules if @core_modules
70
+
71
+ output =
72
+ `#{Gem.ruby} -e 'puts ObjectSpace.each_object(Module).to_a.join("\n")'`
73
+ modules = []
74
+ output.split("\n").each do |name|
75
+ next if name[0] == ?#
76
+ begin
77
+ mod = constantize name
78
+ next unless mod.kind_of? Module
79
+ modules << mod
80
+ rescue NameError, LoadError
81
+ # Delayed loading failure.
82
+ next
83
+ end
84
+ end
85
+
86
+ @core_modules = modules.freeze
87
+ end
88
+ @core_modules = nil
89
+
90
+ # The classes making up the Ruby VM implementation.
91
+ #
92
+ # Note that all classes are modules, so this is a subset of core_modules.
93
+ #
94
+ # @return [Array<Class>] the classes that are present in a vanilla Ruby
95
+ # environment
96
+ def self.core_classes
97
+ return @core_classes if @core_classes
98
+ @core_classes = core_modules.select { |m| m.kind_of? Class }
99
+ @core_classes.freeze
100
+ end
101
+ @core_classes = nil
102
+
103
+ # All methods defined in a class or module.
104
+ #
105
+ # @param [Module] module_or_class a Class or Module instance
106
+ # @return [Array<Method, UnboundMethod>] all the class and instance methods
107
+ # defined by the given Class or Module
108
+ def self.all_methods(module_or_class)
109
+ class_methods(module_or_class) + instance_methods(module_or_class)
110
+ end
111
+
112
+ # All instance methods defined in a class or module.
113
+ #
114
+ # @param [Module] module_or_class a Class or Module instance
115
+ # @return [Array<Method, UnboundMethod>] all the instance methods defined by
116
+ # the given Class or Module
117
+ def self.instance_methods(module_or_class)
118
+ module_or_class.instance_methods.tap do |array|
119
+ array.map! { |name| module_or_class.instance_method name }
120
+ array.select! { |method| method.owner == module_or_class }
121
+ end
122
+ end
123
+
124
+ # All class methods defined in a class or module.
125
+ #
126
+ # Note: the class methods of a class or module are the instance methods of the
127
+ # class or module's meta-class.
128
+ #
129
+ # @param [Module] module_or_class a Class or Module instance
130
+ # @return [Array<Method, UnboundMethod>] all the instance methods defined by
131
+ # the given Class or Module
132
+ def self.class_methods(module_or_class)
133
+ # NOTE: this long-winded approach avoids creating new singleton classes
134
+ method_names = module_or_class.singleton_methods
135
+ return [] if method_names.empty?
136
+ singleton_class = module_or_class.singleton_class
137
+ method_names.tap do |array|
138
+ array.map! { |name| module_or_class.method name }
139
+ array.select! { |method| method.owner == singleton_class }
140
+ end
141
+ end
142
+
143
+ # Resolves the name of a constant into its value.
144
+ #
145
+ # @param [String] name a constant name, potentially including the scope
146
+ # operator ::
147
+ # @return [Object] the value of the constant with the given name
148
+ # @raise [NameError] no constant with the given name is defined
149
+ def self.constantize(name)
150
+ segments = name.split '::'
151
+ value = Object
152
+ segments.each do |segment|
153
+ next if segment.empty?
154
+ value = if value.const_defined? segment
155
+ value.const_get segment
156
+ else
157
+ value.const_missing segment
158
+ end
159
+ end
160
+ value
161
+ end
162
+ end # namespace VmInfo
163
+
164
+ end # namespace Police
@@ -0,0 +1,67 @@
1
+ module Police
2
+
3
+ module VmInfo
4
+ # Classifies the path to a Ruby file based on its provenance.
5
+ #
6
+ # @param [Method, UnboundMethod] method VM information about a method; usually
7
+ # obtained by calling Object#method or Module#instance_method
8
+ # @return [Symbol] :native for methods defined in a low-level language (C/C++
9
+ # for MRI and Rubinius, Java for JRuby), :kernel for methods belonging to
10
+ # the core VM code (Rubinius and JRuby), :stdlib for methods in Ruby's
11
+ # standard library, :gem for methods that are implemented in a loaded Ruby
12
+ # gem, and :app for all other methods (presumably defined in the current
13
+ # application)
14
+ def self.method_source(method)
15
+ location = method.source_location
16
+ return :native if location.nil?
17
+ code_path = location.first
18
+ return :stdlib if stdlib_path?(code_path)
19
+ return :gem if gem_path?(code_path)
20
+ return :kernel if kernel_path?(code_path)
21
+ :app
22
+ end
23
+
24
+ # True if the given source code path belongs to a gem.
25
+ def self.gem_path?(path)
26
+ Gem.default_path.any? { |gem_path| Paths.descendant? path, gem_path }
27
+ end
28
+
29
+ # True if the given source code path belongs to the Ruby standard library.
30
+ def self.stdlib_path?(path)
31
+ # NOTE: assuming the convention that all directories are prepended to the
32
+ # load path throughout a program's execution
33
+ load_paths = $LOAD_PATH
34
+ last_gem_index = -1
35
+ (load_paths.length - 1).downto(0) do |index|
36
+ if gem_path? load_paths[index]
37
+ last_gem_index = index
38
+ break
39
+ end
40
+ end
41
+ stdlib_paths = load_paths[(last_gem_index + 1)..-1]
42
+ stdlib_paths.any? { |stdlib_path| Paths.descendant? path, stdlib_path }
43
+ end
44
+
45
+ # True if the given source code path belongs to the Ruby VM kernel.
46
+ def self.kernel_path?(path)
47
+ !$LOAD_PATH.any? { |load_path| Paths.descendant? path, load_path }
48
+ end
49
+
50
+ # Implementation details.
51
+ # @private
52
+ module Paths
53
+ class <<self
54
+ # True if a path points to a descendant of the directory in anothe
55
+ def descendant?(descendant, dir)
56
+ if descendant.length > dir.length
57
+ descendant[0, dir.length] == dir &&
58
+ descendant[dir.length] == File::SEPARATOR
59
+ else
60
+ descendant == dir
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end # module VmInfo
66
+
67
+ end # namespace Police
@@ -0,0 +1,13 @@
1
+ module Police
2
+
3
+ module VmInfo
4
+ # Fingerprint for the Ruby VM's core and stdlib API.
5
+ #
6
+ # @return [String] a string that contains the Ruby VM's engine name and
7
+ # core version; this should be representative of the
8
+ def self.signature
9
+ Gem.ruby_engine + Gem.ruby_version.segments[0, 3].join('.')
10
+ end
11
+ end # module VmInfo
12
+
13
+ end # namespace Police
@@ -0,0 +1,53 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "police-vminfo"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Victor Costan"]
12
+ s.date = "2012-03-28"
13
+ s.description = "Collects information about the Ruby VM implementation details."
14
+ s.email = "victor@costan.us"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/police-vminfo.rb",
28
+ "lib/police/vminfo.rb",
29
+ "lib/police/vminfo/objects.rb",
30
+ "lib/police/vminfo/paths.rb",
31
+ "lib/police/vminfo/signature.rb",
32
+ "police-vminfo.gemspec",
33
+ "test/helper.rb",
34
+ "test/vminfo/objects_test.rb",
35
+ "test/vminfo/paths_test.rb",
36
+ "test/vminfo/signature_test.rb"
37
+ ]
38
+ s.homepage = "http://github.com/pwnall/police-vminfo"
39
+ s.licenses = ["MIT"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = "1.8.21"
42
+ s.summary = "Information about the Ruby VM internals."
43
+
44
+ if s.respond_to? :specification_version then
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
+ else
49
+ end
50
+ else
51
+ end
52
+ end
53
+
data/test/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'minitest/unit'
11
+ require 'minitest/spec'
12
+
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ require 'police-vminfo'
16
+
17
+ class MiniTest::Unit::TestCase
18
+ end
19
+
20
+ MiniTest::Unit.autorun
@@ -0,0 +1,302 @@
1
+ require File.expand_path('../helper.rb', File.dirname(__FILE__))
2
+
3
+ describe Police::VmInfo do
4
+ CORE_MODULES = [Kernel, Process::Sys]
5
+ GEM_MODULES = [MiniTest]
6
+ MODULES = CORE_MODULES + GEM_MODULES
7
+ CORE_CLASSES = [Object, Encoding::Converter]
8
+ GEM_CLASSES = [MiniTest::Unit]
9
+ CLASSES = CORE_CLASSES + GEM_CLASSES
10
+
11
+ describe '#named_modules' do
12
+ let(:result) { Police::VmInfo.named_modules }
13
+ (MODULES + CLASSES).each do |const|
14
+ it "contains #{const}" do
15
+ result.must_include const
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '#named_classes' do
21
+ let(:result) { Police::VmInfo.named_classes }
22
+
23
+ CLASSES.each do |const|
24
+ it "contains #{const}" do
25
+ result.must_include const
26
+ end
27
+ end
28
+
29
+ MODULES.each do |const|
30
+ it "does not contain #{const}" do
31
+ result.wont_include const
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#all_modules' do
37
+ let(:result) { Police::VmInfo.all_modules }
38
+ (MODULES + CLASSES).each do |const|
39
+ it "contains #{const}" do
40
+ result.must_include const
41
+ end
42
+ end
43
+
44
+ it 'contains anonymous module' do
45
+ anonymous_module = Module.new
46
+ Police::VmInfo.all_modules.must_include anonymous_module
47
+ end
48
+
49
+ it 'contains anonymous class' do
50
+ anonymous_class = Class.new
51
+ Police::VmInfo.all_modules.must_include anonymous_class
52
+ end
53
+ end
54
+
55
+ describe '#all_classes' do
56
+ let(:result) { Police::VmInfo.all_classes }
57
+
58
+ CLASSES.each do |const|
59
+ it "contains #{const}" do
60
+ result.must_include const
61
+ end
62
+ end
63
+
64
+ MODULES.each do |const|
65
+ it "does not contain #{const}" do
66
+ result.wont_include const
67
+ end
68
+ end
69
+
70
+ it 'does not contain anonymous module' do
71
+ anonymous_module = Module.new
72
+ Police::VmInfo.all_classes.wont_include anonymous_module
73
+ end
74
+
75
+ it 'contains anonymous class' do
76
+ anonymous_class = Class.new
77
+ Police::VmInfo.all_classes.must_include anonymous_class
78
+ end
79
+ end
80
+
81
+ describe '#core_modules' do
82
+ let(:result) { Police::VmInfo.core_modules }
83
+
84
+ (CORE_MODULES + CORE_CLASSES).each do |const|
85
+ it "contains #{const}" do
86
+ result.must_include const
87
+ end
88
+ end
89
+
90
+ (GEM_MODULES + GEM_CLASSES).each do |const|
91
+ it "does not contain #{const}" do
92
+ result.wont_include const
93
+ end
94
+ end
95
+ end
96
+
97
+ describe '#code_classes' do
98
+ let(:result) { Police::VmInfo.core_classes }
99
+
100
+ (CORE_CLASSES).each do |const|
101
+ it "contains #{const}" do
102
+ result.must_include const
103
+ end
104
+ end
105
+
106
+ (CORE_MODULES + GEM_MODULES + GEM_CLASSES).each do |const|
107
+ it "does not contain #{const}" do
108
+ result.wont_include const
109
+ end
110
+ end
111
+ end
112
+
113
+ def fixture_module
114
+ Module.new do
115
+ include Enumerable
116
+
117
+ def police_new_module_method; end
118
+ def map; end
119
+
120
+ def self.dup; end
121
+ def self.police_new_module_class_method; end
122
+ end
123
+ end
124
+
125
+ def fixture_class
126
+ Class.new String do
127
+ def police_new_method; end
128
+ def length; end
129
+
130
+ def self.new; end
131
+ def self.police_new_class_method; end
132
+ end
133
+ end
134
+
135
+ describe "#all_methods" do
136
+ describe 'on the fixture module' do
137
+ let :method_names do
138
+ Police::VmInfo.all_methods(fixture_module).map(&:name)
139
+ end
140
+
141
+ it 'contains overridden class methods' do
142
+ method_names.must_include :dup
143
+ end
144
+
145
+ it 'contains new class methods' do
146
+ method_names.must_include :police_new_module_class_method
147
+ end
148
+
149
+ it 'does not contain inherited class methods' do
150
+ method_names.wont_include :clone
151
+ end
152
+
153
+ it 'contains overridden instance methods' do
154
+ method_names.must_include :map
155
+ end
156
+
157
+ it 'contains new instance methods' do
158
+ method_names.must_include :police_new_module_method
159
+ end
160
+
161
+ it 'does not contain inherited instance methods' do
162
+ method_names.wont_include :select
163
+ end
164
+ end
165
+
166
+ describe 'on the fixture class' do
167
+ let :method_names do
168
+ Police::VmInfo.all_methods(fixture_class).map(&:name)
169
+ end
170
+
171
+ it 'contains overridden class methods' do
172
+ method_names.must_include :new
173
+ end
174
+
175
+ it 'contains new class methods' do
176
+ method_names.must_include :police_new_class_method
177
+ end
178
+
179
+ it 'does not contain inherited class methods' do
180
+ method_names.wont_include :superclass
181
+ end
182
+
183
+ it 'contains overridden instance methods' do
184
+ method_names.must_include :length
185
+ end
186
+
187
+ it 'contains new instance methods' do
188
+ method_names.must_include :police_new_method
189
+ end
190
+
191
+ it 'does not contain inherited instance methods' do
192
+ method_names.wont_include :to_s
193
+ end
194
+ end
195
+ end
196
+
197
+ describe "#class_methods" do
198
+ describe 'on the fixture module' do
199
+ let :method_names do
200
+ Police::VmInfo.class_methods(fixture_module).map(&:name)
201
+ end
202
+
203
+ it 'contains overridden methods' do
204
+ method_names.must_include :dup
205
+ end
206
+
207
+ it 'contains new methods' do
208
+ method_names.must_include :police_new_module_class_method
209
+ end
210
+
211
+ it 'does not contain inherited class methods' do
212
+ method_names.wont_include :clone
213
+ end
214
+
215
+ it 'does not contain instance methods' do
216
+ method_names.wont_include :police_new_module_method
217
+ end
218
+ end
219
+
220
+ describe 'on the fixture class' do
221
+ let :method_names do
222
+ Police::VmInfo.class_methods(fixture_class).map(&:name)
223
+ end
224
+
225
+ it 'contains overridden methods' do
226
+ method_names.must_include :new
227
+ end
228
+
229
+ it 'contains new methods' do
230
+ method_names.must_include :police_new_class_method
231
+ end
232
+
233
+ it 'does not contain inherited class methods' do
234
+ method_names.wont_include :superclass
235
+ end
236
+
237
+ it 'does not contain instance methods' do
238
+ method_names.wont_include :police_new_method
239
+ end
240
+ end
241
+ end
242
+
243
+ describe "#instance_methods" do
244
+ describe 'on the fixture module' do
245
+ let :method_names do
246
+ Police::VmInfo.instance_methods(fixture_module).map(&:name)
247
+ end
248
+
249
+ it 'contains overridden methods' do
250
+ method_names.must_include :map
251
+ end
252
+
253
+ it 'contains new methods' do
254
+ method_names.must_include :police_new_module_method
255
+ end
256
+
257
+ it 'does not contain inherited methods' do
258
+ method_names.wont_include :select
259
+ end
260
+
261
+ it 'does not contain class methods' do
262
+ method_names.wont_include :police_new_module_class_method
263
+ end
264
+ end
265
+
266
+ describe 'on the fixture class' do
267
+ let :method_names do
268
+ Police::VmInfo.instance_methods(fixture_class).map(&:name)
269
+ end
270
+
271
+ it 'contains overridden methods' do
272
+ method_names.must_include :length
273
+ end
274
+
275
+ it 'contains new methods' do
276
+ method_names.must_include :police_new_method
277
+ end
278
+
279
+ it 'does not contain inherited methods' do
280
+ method_names.wont_include :to_s
281
+ end
282
+
283
+ it 'does not contain class methods' do
284
+ method_names.wont_include :police_new_class_method
285
+ end
286
+ end
287
+ end
288
+
289
+ describe "#constantize" do
290
+ it 'works on simple names' do
291
+ Police::VmInfo.constantize('Object').must_equal Object
292
+ end
293
+
294
+ it 'works on scoped names' do
295
+ Police::VmInfo.constantize('Process::Sys').must_equal Process::Sys
296
+ end
297
+
298
+ it 'works on global scoped names' do
299
+ Police::VmInfo.constantize('::Process::Sys').must_equal Process::Sys
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,84 @@
1
+ require File.expand_path('../helper.rb', File.dirname(__FILE__))
2
+ require 'net/http'
3
+
4
+ describe Police::VmInfo do
5
+ def some_method; end
6
+
7
+ APP_PATH = Police::VmInfo.method(:gem_path?).source_location.first
8
+ TEST_PATH = self.instance_method(:some_method).source_location.first
9
+ HTTP_PATH = Net::HTTP.method(:new).source_location.first
10
+ BUNDLER_PATH = Bundler.method(:setup).source_location.first
11
+
12
+ describe '#method_source' do
13
+ it 'recognizes stdlib methods' do
14
+ Police::VmInfo.method_source(Net::HTTP.method(:new)).must_equal :stdlib
15
+ end
16
+
17
+ it 'recognizes gem methods' do
18
+ Police::VmInfo.method_source(Bundler.method(:setup)).must_equal :gem
19
+ end
20
+
21
+ it 'recognizes app methods' do
22
+ Police::VmInfo.method_source(Police::VmInfo.method(:gem_path?)).
23
+ must_equal :app
24
+ end
25
+ end
26
+
27
+ describe '#gem_path?' do
28
+ it 'accepts Bundler path' do
29
+ Police::VmInfo.gem_path?(BUNDLER_PATH).must_equal true
30
+ end
31
+
32
+ it 'rejects Net::HTTP path' do
33
+ Police::VmInfo.gem_path?(HTTP_PATH).must_equal false
34
+ end
35
+
36
+ it 'rejects test path' do
37
+ Police::VmInfo.gem_path?(TEST_PATH).must_equal false
38
+ end
39
+
40
+ it 'rejects app path' do
41
+ Police::VmInfo.gem_path?(APP_PATH).must_equal false
42
+ end
43
+ end
44
+
45
+ describe '#stdlib_path?' do
46
+ it 'rejects Bundler path' do
47
+ Police::VmInfo.stdlib_path?(BUNDLER_PATH).must_equal false
48
+ end
49
+
50
+ it 'accepts Net::HTTP path' do
51
+ Police::VmInfo.stdlib_path?(HTTP_PATH).must_equal true
52
+ end
53
+
54
+ it 'rejects test path' do
55
+ Police::VmInfo.stdlib_path?(TEST_PATH).must_equal false
56
+ end
57
+
58
+ it 'rejects app path' do
59
+ Police::VmInfo.stdlib_path?(APP_PATH).must_equal false
60
+ end
61
+ end
62
+
63
+ describe '#kernel_path?' do
64
+ it 'rejects Bundler path' do
65
+ Police::VmInfo.kernel_path?(BUNDLER_PATH).must_equal false
66
+ end
67
+
68
+ it 'rejects Net::HTTP path' do
69
+ Police::VmInfo.kernel_path?(HTTP_PATH).must_equal false
70
+ end
71
+
72
+ it 'rejects test path' do
73
+ Police::VmInfo.kernel_path?(TEST_PATH).must_equal false
74
+ end
75
+
76
+ it 'rejects app path' do
77
+ Police::VmInfo.kernel_path?(APP_PATH).must_equal false
78
+ end
79
+
80
+ it 'accepts a Rubinius kernel path' do
81
+ Police::VmInfo.kernel_path?('kernel/bootstrap/string.rb').must_equal true
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../helper.rb', File.dirname(__FILE__))
2
+
3
+ describe Police::VmInfo do
4
+ describe '#signature' do
5
+ let(:result) { Police::VmInfo.signature }
6
+
7
+ it "should not be empty" do
8
+ result.length.wont_equal 0
9
+ end
10
+
11
+ it "should have a bunch of letters, numbers and .s" do
12
+ result.must_match(/\A\w+[0-9.]+\Z/)
13
+ end
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: police-vminfo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Victor Costan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Collects information about the Ruby VM implementation details.
15
+ email: victor@costan.us
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - LICENSE.txt
20
+ - README.markdown
21
+ files:
22
+ - .document
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - LICENSE.txt
26
+ - README.markdown
27
+ - Rakefile
28
+ - VERSION
29
+ - lib/police-vminfo.rb
30
+ - lib/police/vminfo.rb
31
+ - lib/police/vminfo/objects.rb
32
+ - lib/police/vminfo/paths.rb
33
+ - lib/police/vminfo/signature.rb
34
+ - police-vminfo.gemspec
35
+ - test/helper.rb
36
+ - test/vminfo/objects_test.rb
37
+ - test/vminfo/paths_test.rb
38
+ - test/vminfo/signature_test.rb
39
+ homepage: http://github.com/pwnall/police-vminfo
40
+ licenses:
41
+ - MIT
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ segments:
53
+ - 0
54
+ hash: -2040166733346347996
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.21
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Information about the Ruby VM internals.
67
+ test_files: []