rubybreaker 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +48 -0
- data/README.md +56 -20
- data/Rakefile +9 -34
- data/TODO +10 -10
- data/VERSION +1 -0
- data/bin/gen_stub_rubylib +35 -36
- data/bin/rubybreaker +1 -4
- data/lib/rubybreaker/debug.rb +8 -4
- data/lib/rubybreaker/rubylib/core.rb +738 -571
- data/lib/rubybreaker/runtime/inspector.rb +16 -7
- data/lib/rubybreaker/runtime/monitor.rb +14 -18
- data/lib/rubybreaker/runtime/object_wrapper.rb +9 -3
- data/lib/rubybreaker/runtime/overrides.rb +51 -8
- data/lib/rubybreaker/runtime/pluggable.rb +1 -3
- data/lib/rubybreaker/runtime/type_placeholder.rb +2 -6
- data/lib/rubybreaker/runtime/type_system.rb +53 -17
- data/lib/rubybreaker/runtime/typesig_parser.rb +1 -0
- data/lib/rubybreaker/runtime/util.rb +18 -0
- data/lib/rubybreaker/runtime.rb +42 -15
- data/lib/rubybreaker/type/type_comparer.rb +10 -10
- data/lib/rubybreaker/type/type_grammar.treetop +30 -21
- data/lib/rubybreaker/type/type_unparser.rb +2 -2
- data/lib/rubybreaker/typing/subtyping.rb +21 -21
- data/lib/rubybreaker/util.rb +11 -1
- data/lib/rubybreaker.rb +75 -54
- data/test/integrated/tc_class_methods.rb +35 -0
- data/test/integrated/tc_inherit_broken.rb +29 -0
- data/test/integrated/tc_method_missing.rb +1 -1
- data/test/runtime/tc_obj_wrapper.rb +104 -4
- data/test/ts_integrated.rb +2 -0
- data/test/type/tc_comparer.rb +96 -96
- data/test/type/tc_parser.rb +18 -0
- data/test/type/tc_unparser.rb +16 -0
- data/test/typing/tc_typing.rb +20 -20
- data/webpage/footer.html +1 -1
- data/webpage/header.html +7 -7
- data/webpage/index.html +65 -28
- data/webpage/rdoc/RubyBreaker/Breakable.html +280 -0
- data/webpage/rdoc/RubyBreaker/Broken/BrokenEigen.html +304 -0
- data/webpage/rdoc/RubyBreaker/Broken.html +308 -0
- data/webpage/rdoc/RubyBreaker/Context.html +421 -0
- data/webpage/rdoc/RubyBreaker/Debug.html +411 -0
- data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +263 -0
- data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +263 -0
- data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +214 -0
- data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +212 -0
- data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +212 -0
- data/webpage/rdoc/RubyBreaker/Errors/UserError.html +264 -0
- data/webpage/rdoc/RubyBreaker/Errors.html +209 -0
- data/webpage/rdoc/RubyBreaker/Kernel.html +259 -0
- data/webpage/rdoc/RubyBreaker/Main.html +560 -0
- data/webpage/rdoc/RubyBreaker/ObjectPosition.html +334 -0
- data/webpage/rdoc/RubyBreaker/Position.html +463 -0
- data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +308 -0
- data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +380 -0
- data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +324 -0
- data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +354 -0
- data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +379 -0
- data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +382 -0
- data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +400 -0
- data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +411 -0
- data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +305 -0
- data/webpage/rdoc/RubyBreaker/Runtime/TypePlaceholder.html +280 -0
- data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +283 -0
- data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +630 -0
- data/webpage/rdoc/RubyBreaker/Runtime.html +255 -0
- data/webpage/rdoc/RubyBreaker/TestCase.html +332 -0
- data/webpage/rdoc/RubyBreaker/TypeComparer.html +304 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +260 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +310 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +320 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +323 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +281 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +282 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +260 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +282 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +281 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +281 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +329 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +409 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +282 -0
- data/webpage/rdoc/RubyBreaker/TypeDefs.html +212 -0
- data/webpage/rdoc/RubyBreaker/TypeUnparser.html +273 -0
- data/webpage/rdoc/RubyBreaker/Typing.html +305 -0
- data/webpage/rdoc/RubyBreaker/Utilities.html +294 -0
- data/webpage/rdoc/RubyBreaker.html +337 -0
- data/webpage/rdoc/created.rid +26 -0
- data/webpage/rdoc/images/add.png +0 -0
- data/webpage/rdoc/images/brick.png +0 -0
- data/webpage/rdoc/images/brick_link.png +0 -0
- data/webpage/rdoc/images/bug.png +0 -0
- data/webpage/rdoc/images/bullet_black.png +0 -0
- data/webpage/rdoc/images/bullet_toggle_minus.png +0 -0
- data/webpage/rdoc/images/bullet_toggle_plus.png +0 -0
- data/webpage/rdoc/images/date.png +0 -0
- data/webpage/rdoc/images/delete.png +0 -0
- data/webpage/rdoc/images/find.png +0 -0
- data/webpage/rdoc/images/loadingAnimation.gif +0 -0
- data/webpage/rdoc/images/macFFBgHack.png +0 -0
- data/webpage/rdoc/images/package.png +0 -0
- data/webpage/rdoc/images/page_green.png +0 -0
- data/webpage/rdoc/images/page_white_text.png +0 -0
- data/webpage/rdoc/images/page_white_width.png +0 -0
- data/webpage/rdoc/images/plugin.png +0 -0
- data/webpage/rdoc/images/ruby.png +0 -0
- data/webpage/rdoc/images/tag_blue.png +0 -0
- data/webpage/rdoc/images/tag_green.png +0 -0
- data/webpage/rdoc/images/transparent.png +0 -0
- data/webpage/rdoc/images/wrench.png +0 -0
- data/webpage/rdoc/images/wrench_orange.png +0 -0
- data/webpage/rdoc/images/zoom.png +0 -0
- data/webpage/rdoc/index.html +165 -0
- data/webpage/rdoc/js/darkfish.js +153 -0
- data/webpage/rdoc/js/jquery.js +18 -0
- data/webpage/rdoc/js/navigation.js +142 -0
- data/webpage/rdoc/js/search.js +94 -0
- data/webpage/rdoc/js/search_index.js +1 -0
- data/webpage/rdoc/js/searcher.js +228 -0
- data/webpage/rdoc/rdoc.css +543 -0
- data/webpage/rdoc/table_of_contents.html +376 -0
- data/webpage/rubybreaker.css +31 -31
- metadata +93 -6
@@ -20,8 +20,8 @@ grammar TypeGrammar
|
|
20
20
|
ret = ret_type.value
|
21
21
|
pos = RubyBreaker::Position.get()
|
22
22
|
pos.col = meth_name.interval.first
|
23
|
-
|
24
|
-
|
23
|
+
return RubyBreaker::MethodType.new(mname,args,blk,ret,pos)
|
24
|
+
end
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
@@ -216,15 +216,15 @@ grammar TypeGrammar
|
|
216
216
|
nil_type / any_type1 / self_type / nominal_type
|
217
217
|
end
|
218
218
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
219
|
+
rule self_type
|
220
|
+
'self' {
|
221
|
+
def value
|
222
|
+
pos = RubyBreaker::Position.get()
|
223
|
+
pos.col = interval.first
|
224
|
+
return RubyBreaker::SelfType.new(pos)
|
225
|
+
end
|
226
|
+
}
|
227
|
+
end
|
228
228
|
|
229
229
|
rule nominal_type
|
230
230
|
[a-z_]+ {
|
@@ -264,20 +264,29 @@ grammar TypeGrammar
|
|
264
264
|
end
|
265
265
|
|
266
266
|
rule meth_name
|
267
|
-
|
267
|
+
deprecated_meth_name / normal_meth_name
|
268
268
|
end
|
269
269
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
'==' / '!=' / '<<' / '>>' / '[]' / '**' / '<=' / '>=' / '-@' / '=~' /
|
274
|
-
'<' / '>' / '&' / '|' / '*' / '/' / '%' / '+' / '-' / '^'
|
275
|
-
end
|
270
|
+
rule deprecated_meth_name
|
271
|
+
'_deprecated_' normal_meth_name
|
272
|
+
end
|
276
273
|
|
277
|
-
|
278
|
-
|
279
|
-
|
274
|
+
rule normal_meth_name
|
275
|
+
nominal_meth_name / sym_meth_name
|
276
|
+
end
|
280
277
|
|
278
|
+
rule sym_meth_name
|
279
|
+
# Be careful about the order. Remember, it finds a match first
|
280
|
+
'===' / '<=>' / '[]=' /
|
281
|
+
'!~' / '+@' /
|
282
|
+
'==' / '!=' / '<<' / '>>' / '[]' / '**' / '<=' / '>=' / '-@' / '=~' /
|
283
|
+
'<' / '>' / '&' / '|' / '*' / '/' / '%' / '+' / '-' / '^' / '~'
|
284
|
+
end
|
285
|
+
|
286
|
+
rule nominal_meth_name
|
287
|
+
[a-z_] [a-zA-Z0-9_]* [!?=]?
|
288
|
+
end
|
289
|
+
|
281
290
|
rule space
|
282
291
|
[\s]+
|
283
292
|
end
|
@@ -41,8 +41,8 @@ module RubyBreaker
|
|
41
41
|
tokens = tname.split("/")
|
42
42
|
tname = tokens.last if tokens.size > 1
|
43
43
|
pp.text(tname)
|
44
|
-
|
45
|
-
|
44
|
+
elsif t.instance_of?(SelfType)
|
45
|
+
pp.text("self")
|
46
46
|
elsif t.instance_of?(DuckType)
|
47
47
|
unparse_pp_object_type(pp,t)
|
48
48
|
elsif t.instance_of?(FusionType)
|
@@ -331,23 +331,23 @@ module RubyBreaker
|
|
331
331
|
return is_subtype
|
332
332
|
end
|
333
333
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
334
|
+
# Self type works exactly like nominal type except that, if RHS is a
|
335
|
+
# self type, then only self type is allowed in LHS.
|
336
|
+
#
|
337
|
+
# For example, consider you are inside Fixnum
|
338
|
+
#
|
339
|
+
# self <: Fixnum
|
340
|
+
# self <: Numeric
|
341
|
+
# self <: Object
|
342
|
+
# self <: self
|
343
|
+
#
|
344
|
+
# but,
|
345
|
+
#
|
346
|
+
# Fixnum !<: self
|
347
|
+
#
|
348
|
+
def self.self_subtype_rel?(lhs,rhs)
|
349
|
+
self.nominal_subtype_rel?(lhs,rhs)
|
350
|
+
end
|
351
351
|
|
352
352
|
# This method checks the subtype relation when LHS is a nominal type.
|
353
353
|
# There are several cases to consider:
|
@@ -367,8 +367,8 @@ module RubyBreaker
|
|
367
367
|
def self.nominal_subtype_rel?(lhs,rhs)
|
368
368
|
return false unless lhs.kind_of?(NominalType) # Self type is a nominal type
|
369
369
|
if rhs.instance_of?(SelfType)
|
370
|
-
|
371
|
-
|
370
|
+
is_subtype = lhs.instance_of?(SelfType)
|
371
|
+
elsif rhs.instance_of?(NominalType) # don't include self type
|
372
372
|
is_subtype = RubyTypeUtils.subclass_rel?(lhs.mod, rhs.mod)
|
373
373
|
elsif rhs.instance_of?(FusionType)
|
374
374
|
# If RHS is a superclass or included module then true
|
@@ -444,8 +444,8 @@ module RubyBreaker
|
|
444
444
|
is_subtype = rhs.instance_of?(NilType)
|
445
445
|
elsif lhs.instance_of?(AnyType)
|
446
446
|
is_subtype = true
|
447
|
-
|
448
|
-
|
447
|
+
elsif lhs.instance_of?(SelfType)
|
448
|
+
is_subtype = self.self_subtype_rel?(lhs,rhs)
|
449
449
|
elsif lhs.instance_of?(NominalType)
|
450
450
|
is_subtype = self.nominal_subtype_rel?(lhs,rhs)
|
451
451
|
elsif lhs.instance_of?(FusionType)
|
data/lib/rubybreaker/util.rb
CHANGED
@@ -17,7 +17,7 @@ module RubyBreaker
|
|
17
17
|
word
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
# File activesupport/lib/active_support/inflector/methods.rb
|
21
21
|
def self.camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
22
22
|
if first_letter_in_uppercase
|
23
23
|
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
@@ -28,4 +28,14 @@ module RubyBreaker
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
+
# http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/
|
32
|
+
module Kernel
|
33
|
+
def suppress_warning
|
34
|
+
original_verbosity = $VERBOSE
|
35
|
+
$VERBOSE = nil
|
36
|
+
result = yield
|
37
|
+
$VERBOSE = original_verbosity
|
38
|
+
return result
|
39
|
+
end
|
40
|
+
end
|
31
41
|
end
|
data/lib/rubybreaker.rb
CHANGED
@@ -24,21 +24,10 @@ module RubyBreaker
|
|
24
24
|
:rubylib => true, # include core ruby library documentation?
|
25
25
|
}
|
26
26
|
|
27
|
-
# Broken takes higher precedence than Breakable. Once a module is
|
28
|
-
# "declared" to be Broken, it cannot be Breakable.
|
29
|
-
#
|
30
|
-
# TODO: In future, there will be a module to support both states.
|
31
|
-
|
32
|
-
# This array lists modules/classes that will be monitored.
|
33
|
-
BREAKABLE = []
|
34
|
-
|
35
27
|
# This array lists modules/classes that are actually instrumented with a
|
36
28
|
# monitor.
|
37
29
|
INSTALLED = []
|
38
30
|
|
39
|
-
# This array lists "broken" classes--i.e., with type signatures
|
40
|
-
BROKEN = []
|
41
|
-
|
42
31
|
# This array lists monitored modules/classes that are outputed.
|
43
32
|
DOCUMENTED = []
|
44
33
|
|
@@ -58,14 +47,15 @@ module RubyBreaker
|
|
58
47
|
# module/class.
|
59
48
|
def self.setup()
|
60
49
|
|
61
|
-
BREAKABLE.each do |
|
50
|
+
BREAKABLE.each do |mod|
|
62
51
|
# Avoid already installed module or now Broken module. Remember,
|
63
52
|
# once a module is a declared to be Broken, it wins. Broken modules
|
64
53
|
# cannot be Breakable!
|
65
|
-
unless INSTALLED.include?(
|
66
|
-
MonitorInstaller.install_module_monitor(
|
67
|
-
INSTALLED <<
|
54
|
+
unless INSTALLED.include?(mod) || BROKEN.include?(mod)
|
55
|
+
MonitorInstaller.install_module_monitor(mod)
|
56
|
+
INSTALLED << mod
|
68
57
|
end
|
58
|
+
|
69
59
|
end
|
70
60
|
|
71
61
|
# At the end, we generate an output of the type information.
|
@@ -81,6 +71,71 @@ module RubyBreaker
|
|
81
71
|
eval "load \"#{OPTIONS[:io_file]}\"", TOPLEVEL_BINDING
|
82
72
|
end
|
83
73
|
|
74
|
+
# Pretty prints type information for methods
|
75
|
+
def self.pp_methods(pp, meth_type_map)
|
76
|
+
meth_type_map.each { |meth_name, meth_type|
|
77
|
+
case meth_type
|
78
|
+
when MethodType
|
79
|
+
pp.breakable()
|
80
|
+
pp.text("typesig(\"")
|
81
|
+
TypeUnparser.unparse_pp(pp,meth_type)
|
82
|
+
pp.text("\")")
|
83
|
+
when MethodListType
|
84
|
+
meth_type.types.each { |real_meth_type|
|
85
|
+
pp.breakable()
|
86
|
+
pp.text("typesig(\"")
|
87
|
+
TypeUnparser.unparse_pp(pp,real_meth_type)
|
88
|
+
pp.text("\")")
|
89
|
+
}
|
90
|
+
else
|
91
|
+
# Can't happen
|
92
|
+
end
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
# Pretty prints type information for the module/class
|
97
|
+
def self.pp_module(pp, mod)
|
98
|
+
# Skip it if we already have seen it
|
99
|
+
return if DOCUMENTED.include?(mod) || mod.to_s[0..1] == "#<"
|
100
|
+
|
101
|
+
# Remember that we have documented this module/class
|
102
|
+
DOCUMENTED << mod
|
103
|
+
|
104
|
+
# Get the method type mapping
|
105
|
+
meth_type_map = Inspector.inspect_all(mod)
|
106
|
+
|
107
|
+
# Check if this module is a class
|
108
|
+
keyword = mod.instance_of?(Class) ? "class" : "module"
|
109
|
+
|
110
|
+
pp.text("#{keyword} #{mod.to_s}", 80)
|
111
|
+
pp.nest(2) do
|
112
|
+
pp.breakable("")
|
113
|
+
pp.text("include RubyBreaker::Broken", 80)
|
114
|
+
|
115
|
+
# See if there is any class method to show
|
116
|
+
eigen = Runtime.eigen_class(mod)
|
117
|
+
|
118
|
+
if !DOCUMENTED.include?(eigen)
|
119
|
+
DOCUMENTED << eigen
|
120
|
+
eigen_meth_type_map = Inspector.inspect_all(eigen)
|
121
|
+
if eigen_meth_type_map.size > 0
|
122
|
+
pp.breakable()
|
123
|
+
pp.text("class << self", 80)
|
124
|
+
pp.nest(2) do
|
125
|
+
self.pp_methods(pp, eigen_meth_type_map)
|
126
|
+
end
|
127
|
+
pp.breakable()
|
128
|
+
pp.text("end", 80)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
self.pp_methods(pp, meth_type_map)
|
132
|
+
|
133
|
+
end
|
134
|
+
pp.breakable()
|
135
|
+
pp.text("end",80)
|
136
|
+
pp.breakable()
|
137
|
+
end
|
138
|
+
|
84
139
|
# This method will generate the output
|
85
140
|
def self.output()
|
86
141
|
|
@@ -90,44 +145,11 @@ module RubyBreaker
|
|
90
145
|
pp = PrettyPrint.new(str)
|
91
146
|
|
92
147
|
# Document each module that was monitored
|
93
|
-
INSTALLED.each
|
94
|
-
|
95
|
-
# Skip it if we already have seen it
|
96
|
-
next if DOCUMENTED.include?(mod)
|
97
|
-
DOCUMENTED << mod
|
98
|
-
|
99
|
-
pp.text("class #{mod.to_s}")
|
100
|
-
pp.nest(2) do
|
101
|
-
pp.breakable("")
|
102
|
-
pp.text("include RubyBreaker::Broken")
|
103
|
-
meth_type_map = Inspector.inspect_all(mod)
|
104
|
-
meth_type_map.each { |meth_name, meth_type|
|
105
|
-
case meth_type
|
106
|
-
when MethodType
|
107
|
-
pp.breakable()
|
108
|
-
pp.text("typesig(\"")
|
109
|
-
TypeUnparser.unparse_pp(pp,meth_type)
|
110
|
-
pp.text("\")")
|
111
|
-
when MethodListType
|
112
|
-
meth_type.types.each { |real_meth_type|
|
113
|
-
pp.breakable()
|
114
|
-
pp.text("typesig(\"")
|
115
|
-
TypeUnparser.unparse_pp(pp,real_meth_type)
|
116
|
-
pp.text("\")")
|
117
|
-
}
|
118
|
-
else
|
119
|
-
# Can't happen
|
120
|
-
end
|
121
|
-
}
|
122
|
-
end
|
123
|
-
pp.breakable()
|
124
|
-
pp.text("end")
|
125
|
-
pp.breakable()
|
126
|
-
end
|
148
|
+
INSTALLED.each { |mod| self.pp_module(pp, mod) }
|
127
149
|
pp.flush
|
128
150
|
|
129
151
|
# First, display the result on the stdout if set
|
130
|
-
|
152
|
+
print str if OPTIONS[:stdout]
|
131
153
|
|
132
154
|
# If this was a library mode run, exit now.
|
133
155
|
return if OPTIONS[:mode] == :lib
|
@@ -136,11 +158,10 @@ module RubyBreaker
|
|
136
158
|
open(OPTIONS[:io_file],"a") do |f|
|
137
159
|
unless io_exist
|
138
160
|
f.puts "# This file is auto-generated by RubyBreaker"
|
139
|
-
|
161
|
+
f.puts "require \"rubybreaker\""
|
140
162
|
end
|
141
163
|
f.puts str
|
142
164
|
end
|
143
|
-
|
144
165
|
end
|
145
166
|
|
146
167
|
# This method will run the input file
|
@@ -170,7 +191,7 @@ module RubyBreaker
|
|
170
191
|
|
171
192
|
if OPTIONS[:rubylib]
|
172
193
|
# Load the core library type documentation
|
173
|
-
eval("require \"
|
194
|
+
eval("require \"rubybreaker/rubylib\"", TOPLEVEL_BINDING)
|
174
195
|
end
|
175
196
|
|
176
197
|
# Read the input file first (as it might contain type documentation
|
@@ -178,7 +199,7 @@ module RubyBreaker
|
|
178
199
|
Main.input()
|
179
200
|
|
180
201
|
# Finally, require the program file! Let it run! Wheeee!
|
181
|
-
eval
|
202
|
+
eval("require '#{prog_file}'", TOPLEVEL_BINDING)
|
182
203
|
|
183
204
|
end
|
184
205
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "../../lib/rubybreaker"
|
3
|
+
|
4
|
+
class IntegratedClassMethodsTest < Test::Unit::TestCase
|
5
|
+
include RubyBreaker
|
6
|
+
include RubyBreaker::TestCase
|
7
|
+
|
8
|
+
class A
|
9
|
+
include RubyBreaker::Breakable
|
10
|
+
def self.foo(x); x.to_s end
|
11
|
+
end
|
12
|
+
|
13
|
+
class B
|
14
|
+
include RubyBreaker::Broken
|
15
|
+
class << self
|
16
|
+
typesig("bar(fixnum[to_s]) -> string")
|
17
|
+
def bar(x); x.to_s end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_class_methods
|
22
|
+
A.foo(1)
|
23
|
+
a_foo_meth_type = Runtime::Inspector.inspect_class_meth(A, :foo)
|
24
|
+
str = RubyBreaker::TypeUnparser.unparse(a_foo_meth_type)
|
25
|
+
assert_equal("foo(fixnum[to_s]) -> string", str)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_broken_class_methods
|
29
|
+
b_bar_meth_type = Runtime::Inspector.inspect_class_meth(B, :bar)
|
30
|
+
str = RubyBreaker::TypeUnparser.unparse(b_bar_meth_type)
|
31
|
+
assert_equal("bar(fixnum[to_s]) -> string", str)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "../../lib/rubybreaker"
|
3
|
+
|
4
|
+
class IntegratedInheritBrokenTest < Test::Unit::TestCase
|
5
|
+
include RubyBreaker
|
6
|
+
include RubyBreaker::TestCase
|
7
|
+
|
8
|
+
class A
|
9
|
+
include RubyBreaker::Broken
|
10
|
+
typesig("foo(fixnum[to_s]) -> string")
|
11
|
+
def foo(x); x.to_s end
|
12
|
+
end
|
13
|
+
|
14
|
+
class B < A
|
15
|
+
include RubyBreaker::Breakable
|
16
|
+
def bar(x); foo(x) end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_both
|
20
|
+
b = B.new
|
21
|
+
b.bar(1)
|
22
|
+
b_meth_type = Runtime::Inspector.inspect_meth(B, :bar)
|
23
|
+
str = RubyBreaker::TypeUnparser.unparse(b_meth_type)
|
24
|
+
assert_equal("bar(fixnum[to_s]) -> string", str)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
@@ -23,7 +23,7 @@ class IntegratedMethodMissingTest < Test::Unit::TestCase
|
|
23
23
|
meth_type = Runtime::Inspector.inspect_meth(A, :method_missing)
|
24
24
|
str = RubyBreaker::TypeUnparser.unparse(meth_type)
|
25
25
|
# puts str
|
26
|
-
assert_equal("method_missing(symbol[to_s], fixnum[to_s]
|
26
|
+
assert_equal("method_missing(symbol[to_s], fixnum[to_s]*) -> string", str, "A#foo failed.")
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
dir = File.dirname(__FILE__)
|
2
1
|
require "test/unit"
|
3
|
-
|
2
|
+
require_relative "../../lib/rubybreaker/runtime"
|
4
3
|
|
5
4
|
class ObjectWrapperTest < Test::Unit::TestCase
|
6
5
|
include RubyBreaker
|
@@ -54,7 +53,7 @@ class ObjectWrapperTest < Test::Unit::TestCase
|
|
54
53
|
assert_equal(x.object_id, wrapped_x.object_id)
|
55
54
|
end
|
56
55
|
|
57
|
-
def
|
56
|
+
def test_equalities_fixnum()
|
58
57
|
x = 42
|
59
58
|
wrapped_x = Runtime::ObjectWrapper.new(x)
|
60
59
|
assert(wrapped_x == wrapped_x)
|
@@ -62,7 +61,7 @@ class ObjectWrapperTest < Test::Unit::TestCase
|
|
62
61
|
assert(wrapped_x.eql?(wrapped_x))
|
63
62
|
assert(42 == wrapped_x)
|
64
63
|
assert(wrapped_x == 42)
|
65
|
-
assert(42.equal?(wrapped_x))
|
64
|
+
assert(42.equal?(wrapped_x)) # try 42.equal?(42) in irb, it will work!
|
66
65
|
assert(wrapped_x.equal?(42))
|
67
66
|
assert(42.eql?(wrapped_x))
|
68
67
|
assert(wrapped_x.eql?(42))
|
@@ -70,4 +69,105 @@ class ObjectWrapperTest < Test::Unit::TestCase
|
|
70
69
|
assert_equal(42, wrapped_x)
|
71
70
|
end
|
72
71
|
|
72
|
+
def test_equalities_string()
|
73
|
+
x = "42"
|
74
|
+
y = "42"
|
75
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
76
|
+
assert(wrapped_x == wrapped_x)
|
77
|
+
assert(wrapped_x.equal?(wrapped_x))
|
78
|
+
assert(wrapped_x.eql?(wrapped_x))
|
79
|
+
assert(y == wrapped_x)
|
80
|
+
assert(wrapped_x == y)
|
81
|
+
assert(!y.equal?(wrapped_x)) # try "42".equal?("42") in irb, it will fail
|
82
|
+
assert(wrapped_x.equal?(y))
|
83
|
+
assert(y.eql?(wrapped_x))
|
84
|
+
assert(wrapped_x.eql?(y))
|
85
|
+
assert_equal(y, wrapped_x)
|
86
|
+
assert_equal(y, wrapped_x)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_equalities_symbol()
|
90
|
+
x = :"42"
|
91
|
+
y = :"42"
|
92
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
93
|
+
assert(wrapped_x == wrapped_x)
|
94
|
+
assert(wrapped_x.equal?(wrapped_x))
|
95
|
+
assert(wrapped_x.eql?(wrapped_x))
|
96
|
+
assert(y == wrapped_x)
|
97
|
+
assert(wrapped_x == y)
|
98
|
+
assert(y.equal?(wrapped_x)) # try :"42".equal?(:"42") in irb, it will work
|
99
|
+
assert(wrapped_x.equal?(y))
|
100
|
+
assert(y.eql?(wrapped_x))
|
101
|
+
assert(wrapped_x.eql?(y))
|
102
|
+
assert_equal(y, wrapped_x)
|
103
|
+
assert_equal(y, wrapped_x)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_equalities_array()
|
107
|
+
x = [1,2]
|
108
|
+
y = [1,2]
|
109
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
110
|
+
assert(wrapped_x == wrapped_x)
|
111
|
+
assert(wrapped_x.equal?(wrapped_x))
|
112
|
+
assert(wrapped_x.eql?(wrapped_x))
|
113
|
+
assert(y == wrapped_x)
|
114
|
+
assert(wrapped_x == y)
|
115
|
+
assert(!y.equal?(wrapped_x))
|
116
|
+
assert(wrapped_x.equal?(y))
|
117
|
+
assert(y.eql?(wrapped_x))
|
118
|
+
assert(wrapped_x.eql?(y))
|
119
|
+
assert_equal(y, wrapped_x)
|
120
|
+
assert_equal(y, wrapped_x)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_inequalities_array()
|
124
|
+
x = [1,2]
|
125
|
+
y = [1,3]
|
126
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
127
|
+
assert(wrapped_x == wrapped_x)
|
128
|
+
assert(wrapped_x.equal?(wrapped_x))
|
129
|
+
assert(wrapped_x.eql?(wrapped_x))
|
130
|
+
assert(y != wrapped_x)
|
131
|
+
assert(wrapped_x != y)
|
132
|
+
assert(!y.equal?(wrapped_x))
|
133
|
+
assert(!wrapped_x.equal?(y))
|
134
|
+
assert(!y.eql?(wrapped_x))
|
135
|
+
assert(!wrapped_x.eql?(y))
|
136
|
+
assert_not_equal(y, wrapped_x)
|
137
|
+
assert_not_equal(y, wrapped_x)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_equalities_hash()
|
141
|
+
x = { :a => 1, :b => 2}
|
142
|
+
y = { :a => 1, :b => 2}
|
143
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
144
|
+
assert(wrapped_x == wrapped_x)
|
145
|
+
assert(wrapped_x.equal?(wrapped_x))
|
146
|
+
assert(wrapped_x.eql?(wrapped_x))
|
147
|
+
assert(y == wrapped_x)
|
148
|
+
assert(wrapped_x == y)
|
149
|
+
assert(!y.equal?(wrapped_x))
|
150
|
+
assert(wrapped_x.equal?(y))
|
151
|
+
assert(y.eql?(wrapped_x))
|
152
|
+
assert(wrapped_x.eql?(y))
|
153
|
+
assert_equal(y, wrapped_x)
|
154
|
+
assert_equal(y, wrapped_x)
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_inequalities_hash()
|
158
|
+
x = { :a => 1, :b => 2}
|
159
|
+
y = { :a => 1, :b => 3}
|
160
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
161
|
+
assert(wrapped_x == wrapped_x)
|
162
|
+
assert(wrapped_x.equal?(wrapped_x))
|
163
|
+
assert(wrapped_x.eql?(wrapped_x))
|
164
|
+
assert(y != wrapped_x)
|
165
|
+
assert(wrapped_x != y)
|
166
|
+
assert(!y.equal?(wrapped_x))
|
167
|
+
assert(!wrapped_x.equal?(y))
|
168
|
+
assert(!y.eql?(wrapped_x))
|
169
|
+
assert(!wrapped_x.eql?(y))
|
170
|
+
assert_not_equal(y, wrapped_x)
|
171
|
+
assert_not_equal(y, wrapped_x)
|
172
|
+
end
|
73
173
|
end
|