rubybreaker 0.0.1 → 0.0.2

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 (122) hide show
  1. data/NEWS +48 -0
  2. data/README.md +56 -20
  3. data/Rakefile +9 -34
  4. data/TODO +10 -10
  5. data/VERSION +1 -0
  6. data/bin/gen_stub_rubylib +35 -36
  7. data/bin/rubybreaker +1 -4
  8. data/lib/rubybreaker/debug.rb +8 -4
  9. data/lib/rubybreaker/rubylib/core.rb +738 -571
  10. data/lib/rubybreaker/runtime/inspector.rb +16 -7
  11. data/lib/rubybreaker/runtime/monitor.rb +14 -18
  12. data/lib/rubybreaker/runtime/object_wrapper.rb +9 -3
  13. data/lib/rubybreaker/runtime/overrides.rb +51 -8
  14. data/lib/rubybreaker/runtime/pluggable.rb +1 -3
  15. data/lib/rubybreaker/runtime/type_placeholder.rb +2 -6
  16. data/lib/rubybreaker/runtime/type_system.rb +53 -17
  17. data/lib/rubybreaker/runtime/typesig_parser.rb +1 -0
  18. data/lib/rubybreaker/runtime/util.rb +18 -0
  19. data/lib/rubybreaker/runtime.rb +42 -15
  20. data/lib/rubybreaker/type/type_comparer.rb +10 -10
  21. data/lib/rubybreaker/type/type_grammar.treetop +30 -21
  22. data/lib/rubybreaker/type/type_unparser.rb +2 -2
  23. data/lib/rubybreaker/typing/subtyping.rb +21 -21
  24. data/lib/rubybreaker/util.rb +11 -1
  25. data/lib/rubybreaker.rb +75 -54
  26. data/test/integrated/tc_class_methods.rb +35 -0
  27. data/test/integrated/tc_inherit_broken.rb +29 -0
  28. data/test/integrated/tc_method_missing.rb +1 -1
  29. data/test/runtime/tc_obj_wrapper.rb +104 -4
  30. data/test/ts_integrated.rb +2 -0
  31. data/test/type/tc_comparer.rb +96 -96
  32. data/test/type/tc_parser.rb +18 -0
  33. data/test/type/tc_unparser.rb +16 -0
  34. data/test/typing/tc_typing.rb +20 -20
  35. data/webpage/footer.html +1 -1
  36. data/webpage/header.html +7 -7
  37. data/webpage/index.html +65 -28
  38. data/webpage/rdoc/RubyBreaker/Breakable.html +280 -0
  39. data/webpage/rdoc/RubyBreaker/Broken/BrokenEigen.html +304 -0
  40. data/webpage/rdoc/RubyBreaker/Broken.html +308 -0
  41. data/webpage/rdoc/RubyBreaker/Context.html +421 -0
  42. data/webpage/rdoc/RubyBreaker/Debug.html +411 -0
  43. data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +263 -0
  44. data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +263 -0
  45. data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +214 -0
  46. data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +212 -0
  47. data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +212 -0
  48. data/webpage/rdoc/RubyBreaker/Errors/UserError.html +264 -0
  49. data/webpage/rdoc/RubyBreaker/Errors.html +209 -0
  50. data/webpage/rdoc/RubyBreaker/Kernel.html +259 -0
  51. data/webpage/rdoc/RubyBreaker/Main.html +560 -0
  52. data/webpage/rdoc/RubyBreaker/ObjectPosition.html +334 -0
  53. data/webpage/rdoc/RubyBreaker/Position.html +463 -0
  54. data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +308 -0
  55. data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +380 -0
  56. data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +324 -0
  57. data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +354 -0
  58. data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +379 -0
  59. data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +382 -0
  60. data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +400 -0
  61. data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +411 -0
  62. data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +305 -0
  63. data/webpage/rdoc/RubyBreaker/Runtime/TypePlaceholder.html +280 -0
  64. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +283 -0
  65. data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +630 -0
  66. data/webpage/rdoc/RubyBreaker/Runtime.html +255 -0
  67. data/webpage/rdoc/RubyBreaker/TestCase.html +332 -0
  68. data/webpage/rdoc/RubyBreaker/TypeComparer.html +304 -0
  69. data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +260 -0
  70. data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +310 -0
  71. data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +320 -0
  72. data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +323 -0
  73. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +281 -0
  74. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +282 -0
  75. data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +260 -0
  76. data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +282 -0
  77. data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +281 -0
  78. data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +281 -0
  79. data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +329 -0
  80. data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +409 -0
  81. data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +282 -0
  82. data/webpage/rdoc/RubyBreaker/TypeDefs.html +212 -0
  83. data/webpage/rdoc/RubyBreaker/TypeUnparser.html +273 -0
  84. data/webpage/rdoc/RubyBreaker/Typing.html +305 -0
  85. data/webpage/rdoc/RubyBreaker/Utilities.html +294 -0
  86. data/webpage/rdoc/RubyBreaker.html +337 -0
  87. data/webpage/rdoc/created.rid +26 -0
  88. data/webpage/rdoc/images/add.png +0 -0
  89. data/webpage/rdoc/images/brick.png +0 -0
  90. data/webpage/rdoc/images/brick_link.png +0 -0
  91. data/webpage/rdoc/images/bug.png +0 -0
  92. data/webpage/rdoc/images/bullet_black.png +0 -0
  93. data/webpage/rdoc/images/bullet_toggle_minus.png +0 -0
  94. data/webpage/rdoc/images/bullet_toggle_plus.png +0 -0
  95. data/webpage/rdoc/images/date.png +0 -0
  96. data/webpage/rdoc/images/delete.png +0 -0
  97. data/webpage/rdoc/images/find.png +0 -0
  98. data/webpage/rdoc/images/loadingAnimation.gif +0 -0
  99. data/webpage/rdoc/images/macFFBgHack.png +0 -0
  100. data/webpage/rdoc/images/package.png +0 -0
  101. data/webpage/rdoc/images/page_green.png +0 -0
  102. data/webpage/rdoc/images/page_white_text.png +0 -0
  103. data/webpage/rdoc/images/page_white_width.png +0 -0
  104. data/webpage/rdoc/images/plugin.png +0 -0
  105. data/webpage/rdoc/images/ruby.png +0 -0
  106. data/webpage/rdoc/images/tag_blue.png +0 -0
  107. data/webpage/rdoc/images/tag_green.png +0 -0
  108. data/webpage/rdoc/images/transparent.png +0 -0
  109. data/webpage/rdoc/images/wrench.png +0 -0
  110. data/webpage/rdoc/images/wrench_orange.png +0 -0
  111. data/webpage/rdoc/images/zoom.png +0 -0
  112. data/webpage/rdoc/index.html +165 -0
  113. data/webpage/rdoc/js/darkfish.js +153 -0
  114. data/webpage/rdoc/js/jquery.js +18 -0
  115. data/webpage/rdoc/js/navigation.js +142 -0
  116. data/webpage/rdoc/js/search.js +94 -0
  117. data/webpage/rdoc/js/search_index.js +1 -0
  118. data/webpage/rdoc/js/searcher.js +228 -0
  119. data/webpage/rdoc/rdoc.css +543 -0
  120. data/webpage/rdoc/table_of_contents.html +376 -0
  121. data/webpage/rubybreaker.css +31 -31
  122. 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
- return RubyBreaker::MethodType.new(mname,args,blk,ret,pos)
24
- end
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
- 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
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
- nominal_meth_name / sym_meth_name
267
+ deprecated_meth_name / normal_meth_name
268
268
  end
269
269
 
270
- rule sym_meth_name
271
- # Be careful about the order. Remember, it finds a match first
272
- '===' / '<=>' / '[]=' /
273
- '==' / '!=' / '<<' / '>>' / '[]' / '**' / '<=' / '>=' / '-@' / '=~' /
274
- '<' / '>' / '&' / '|' / '*' / '/' / '%' / '+' / '-' / '^'
275
- end
270
+ rule deprecated_meth_name
271
+ '_deprecated_' normal_meth_name
272
+ end
276
273
 
277
- rule nominal_meth_name
278
- [a-z_] [a-zA-Z0-9_]* [!?=]?
279
- end
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
- elsif t.instance_of?(SelfType)
45
- pp.text("self")
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
- # 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
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
- is_subtype = lhs.instance_of?(SelfType)
371
- elsif rhs.instance_of?(NominalType) # don't include self type
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
- elsif lhs.instance_of?(SelfType)
448
- is_subtype = self.self_subtype_rel?(lhs,rhs)
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)
@@ -17,7 +17,7 @@ module RubyBreaker
17
17
  word
18
18
  end
19
19
 
20
- # File activesupport/lib/active_support/inflector/methods.rb
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 |m|
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?(m) || BROKEN.include?(m)
66
- MonitorInstaller.install_module_monitor(m,true)
67
- INSTALLED << m
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 do |mod|
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
- puts str if OPTIONS[:stdout]
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
- # f.puts "require \"rubybreaker\""
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 \"#{File.dirname(__FILE__)}/rubybreaker/rubylib\"", TOPLEVEL_BINDING)
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 "require '#{prog_file}'", TOPLEVEL_BINDING
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], fixnum[to_s]) -> string", str, "A#foo failed.")
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
- require "#{dir}/../../lib/rubybreaker/runtime"
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 test_equal()
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
@@ -2,3 +2,5 @@
2
2
  require "test/unit"
3
3
  require_relative "integrated/tc_method_missing"
4
4
  require_relative "integrated/tc_simple1"
5
+ require_relative "integrated/tc_inherit_broken"
6
+ require_relative "integrated/tc_class_methods"