rubybreaker 0.0.1 → 0.0.2

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