rubybreaker 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/NEWS +5 -0
  2. data/NOTES +9 -0
  3. data/README.md +100 -183
  4. data/Rakefile +21 -6
  5. data/VERSION +1 -1
  6. data/bin/rubybreaker +34 -50
  7. data/lib/rubybreaker/debug/debug.rb +6 -0
  8. data/lib/rubybreaker/doc/rdoc.rb +37 -0
  9. data/lib/rubybreaker/doc.rb +3 -0
  10. data/lib/rubybreaker/runtime/inspector.rb +6 -28
  11. data/lib/rubybreaker/runtime/monitor.rb +21 -17
  12. data/lib/rubybreaker/runtime/object_wrapper.rb +7 -2
  13. data/lib/rubybreaker/runtime/type_system.rb +3 -5
  14. data/lib/rubybreaker/runtime/typesig_unparser.rb +1 -4
  15. data/lib/rubybreaker/runtime.rb +64 -105
  16. data/lib/rubybreaker/task.rb +97 -0
  17. data/lib/rubybreaker/test/rspec.rb +1 -1
  18. data/lib/rubybreaker/test/testcase.rb +13 -28
  19. data/lib/rubybreaker/type/type.rb +1 -1
  20. data/lib/rubybreaker/typing/subtyping.rb +10 -5
  21. data/lib/rubybreaker/util.rb +0 -1
  22. data/lib/rubybreaker.rb +163 -115
  23. data/test/integrated/tc_both_broken_breakable.rb +5 -4
  24. data/test/integrated/tc_class_methods.rb +4 -3
  25. data/test/integrated/tc_inherit_broken.rb +4 -3
  26. data/test/integrated/tc_method_missing.rb +4 -4
  27. data/test/integrated/tc_namespace.rb +4 -2
  28. data/test/integrated/tc_simple1.rb +4 -3
  29. data/test/runtime/tc_obj_wrapper.rb +25 -6
  30. data/test/runtime/tc_typesig_parser.rb +0 -1
  31. data/test/testtask/sample.rb +10 -0
  32. data/test/testtask/tc_testtask.rb +25 -0
  33. data/test/ts_rspec.rb +21 -15
  34. data/test/typing/tc_typing.rb +2 -3
  35. data/webpage/index.html +105 -193
  36. data/webpage/rdoc/Kernel.html +286 -0
  37. data/webpage/rdoc/Object.html +17 -11
  38. data/webpage/rdoc/Rake/RubyBreakerTestTask.html +374 -0
  39. data/webpage/rdoc/Rake.html +212 -0
  40. data/webpage/rdoc/RubyBreaker/Breakable.html +24 -40
  41. data/webpage/rdoc/RubyBreaker/Broken.html +21 -69
  42. data/webpage/rdoc/RubyBreaker/Context.html +16 -10
  43. data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +16 -10
  44. data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +16 -10
  45. data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +16 -10
  46. data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +16 -10
  47. data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +16 -10
  48. data/webpage/rdoc/RubyBreaker/Errors/UserError.html +16 -10
  49. data/webpage/rdoc/RubyBreaker/Errors.html +16 -10
  50. data/webpage/rdoc/RubyBreaker/ObjectPosition.html +16 -10
  51. data/webpage/rdoc/RubyBreaker/Position.html +16 -10
  52. data/webpage/rdoc/RubyBreaker/{TestCase.html → RDocSupport.html} +81 -82
  53. data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +16 -10
  54. data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +25 -44
  55. data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +16 -10
  56. data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +19 -13
  57. data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +37 -25
  58. data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +20 -14
  59. data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +21 -15
  60. data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +23 -12
  61. data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +16 -10
  62. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +16 -10
  63. data/webpage/rdoc/RubyBreaker/Runtime/{TypesigUnparser.html → TypeSigUnparser.html} +19 -16
  64. data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +18 -14
  65. data/webpage/rdoc/RubyBreaker/Runtime.html +145 -11
  66. data/webpage/rdoc/RubyBreaker/TypeComparer.html +16 -10
  67. data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +16 -10
  68. data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +16 -10
  69. data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +16 -10
  70. data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +16 -10
  71. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +16 -10
  72. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +16 -10
  73. data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +16 -10
  74. data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +16 -10
  75. data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +16 -10
  76. data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +16 -10
  77. data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +17 -11
  78. data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +17 -11
  79. data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +16 -10
  80. data/webpage/rdoc/RubyBreaker/TypeDefs.html +16 -10
  81. data/webpage/rdoc/RubyBreaker/TypeUnparser.html +16 -10
  82. data/webpage/rdoc/RubyBreaker/Typing.html +17 -11
  83. data/webpage/rdoc/RubyBreaker/Util.html +16 -10
  84. data/webpage/rdoc/RubyBreaker.html +167 -34
  85. data/webpage/rdoc/{RubyBreaker/Runtime/TypePlaceholder.html → Test/Unit/TestCase.html} +68 -39
  86. data/webpage/rdoc/Test/Unit.html +211 -0
  87. data/webpage/rdoc/Test.html +211 -0
  88. data/webpage/rdoc/created.rid +18 -17
  89. data/webpage/rdoc/index.html +16 -10
  90. data/webpage/rdoc/js/search_index.js +1 -1
  91. data/webpage/rdoc/table_of_contents.html +61 -48
  92. metadata +21 -12
  93. data/lib/rubybreaker/rubylib/core.rb +0 -2483
  94. data/lib/rubybreaker/rubylib.rb +0 -3
  95. data/lib/rubybreaker/runtime/type_placeholder.rb +0 -23
  96. data/webpage/rdoc/RubyBreaker/Broken/BrokenEigen.html +0 -305
  97. data/webpage/rdoc/RubyBreaker/Main.html +0 -458
data/lib/rubybreaker.rb CHANGED
@@ -3,164 +3,212 @@
3
3
  # observed at runtime and generates type annotation at the end. It can be
4
4
  # run as either a stand-alone script or as a Ruby library.
5
5
 
6
+ require "set"
7
+ require "optparse"
6
8
  require_relative "rubybreaker/debug"
7
9
  require_relative "rubybreaker/runtime"
8
10
  require_relative "rubybreaker/test"
9
11
 
10
12
  # RubyBreaker is a dynamic instrumentation and monitoring tool that
11
- # documents type information automatically.
13
+ # generates type documentation for Ruby programs.
12
14
  module RubyBreaker
13
-
14
- # This constant contains the copyright information.
15
- COPYRIGHT = "Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved."
15
+ include TypeDefs
16
+ include Runtime
16
17
 
17
18
  # Options for RubyBreaker
18
19
  OPTIONS = {
19
- :debug => false, # in debug mode?
20
- :verbose => false, # in RubyBreaker.verbose mode?
21
- :mode => :lib, # bin or lib?
22
- :io_file => nil, # generate input/output other than default?
23
- :append => true, # append to the input file (if there is)?
24
- :stdout => true, # also display on the screen?
25
- :rubylib => true, # include core ruby library documentation?
26
- :file => nil, # the input Ruby program (as typed by the user)
20
+ :debug => false, # in debug mode?
21
+ :style => :underscore, # type signature style-underscore or camelize
22
+ :io_file => nil, # generate input/output other than default?
23
+ :append => false, # append to the input file (if there is)?
24
+ :stdout => false, # also display on the screen?
25
+ :verbose => false, # in RubyBreaker.verbose mode?
26
+ :save_output => true, # save output to a file?
27
+ :prog_file => nil, # INTERNAL USE ONLY
27
28
  }
28
29
 
29
- # This array lists modules/classes that are actually instrumented with a
30
- # monitor.
31
- INSTALLED = []
32
-
33
- # Extension used by RubyBreaker for output/input
34
- EXTENSION = "rubybreaker"
35
-
36
- # This module has a set of entry points to the program and misc. methods
37
- # for running RubyBreaker.
38
- module Main
30
+ # This option parser may be used for the command-line mode or for the
31
+ # library mode when used with Rakefile. See rubybreaker/task.rb for how
32
+ # this can be used in the latter.
33
+ OPTION_PARSER = OptionParser.new do |opts|
39
34
 
40
- include TypeDefs
41
- include Runtime
35
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] prog[.rb]"
42
36
 
43
- public
37
+ opts.on("--debug", "Run in debug mode") do
38
+ OPTIONS[:debug] = true
39
+ end
44
40
 
45
- # This method is the trigger point to install a monitor in each
46
- # module/class.
47
- def self.setup()
41
+ opts.on("--style STYLE", "Select type signature style - underscore or camelize") do |v|
42
+ OPTIONS[:style] = v.downcase.to_sym
43
+ end
48
44
 
49
- BREAKABLE.each do |mod|
45
+ opts.on("--io-file FILE","Specify I/O file") do |f|
46
+ OPTIONS[:io_file] = f
47
+ end
50
48
 
51
- # Remember, RubyBreaker now supports a hybrid of Breakable and
52
- # Broken module. Just check if the module has already been
53
- # instrumented.
54
- unless INSTALLED.include?(mod)
55
- MonitorInstaller.install_module_monitor(mod)
56
- INSTALLED << mod
57
- end
49
+ opts.on("--save-output", "Save output to file") do b|
50
+ OPTIONS[:save_output] = b
51
+ end
58
52
 
59
- end
53
+ opts.on("-s","--[no-]stdout","Show output on screen") do |b|
54
+ OPTIONS[:stdout] = b
55
+ end
60
56
 
61
- # At the end, we generate an output of the type information.
62
- at_exit do
63
- self.output
64
- end
57
+ opts.on("-a", "--[no-]append", "Append output to input file") do |b|
58
+ OPTIONS[:append] = b
59
+ end
65
60
 
61
+ opts.on("-v","--verbose","Show messages in detail") do
62
+ OPTIONS[:verbose] = true
66
63
  end
67
64
 
68
- # Reads the input file if specified or exists
69
- def self.input()
70
- return unless OPTIONS[:io_file] && File.exist?(OPTIONS[:io_file])
71
- RubyBreaker.verbose("RubyBreaker input file exists...loading")
72
- eval "load \"#{OPTIONS[:io_file]}\"", TOPLEVEL_BINDING
65
+ opts.on("-h","--help","Show this help text") do
66
+ puts opts
67
+ exit
73
68
  end
74
69
 
75
- # This method will generate the output.
76
- def self.output()
70
+ end
77
71
 
78
- RubyBreaker.verbose("Generating type documentation")
72
+ # This constant contains the copyright information.
73
+ COPYRIGHT = "Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved."
79
74
 
80
- io_exist = OPTIONS[:io_file] && File.exist?(OPTIONS[:io_file])
75
+ # Extension used for files that contain RubyBreaker task information
76
+ TASK_EXTENSION = "rb"
81
77
 
82
- code = ""
83
- # Document each module that was monitored
84
- INSTALLED.each { |mod|
85
- str = Runtime::TypesigUnparser.unparse(mod)
86
- code << str
87
- if OPTIONS[:mode] == :lib
88
- print str
89
- end
90
- }
78
+ # Extension used for files that contain type information in YAML format
79
+ YAML_EXTENSION = "yaml"
80
+
81
+ # Extension used for files that contain type information in Ruby format
82
+ IO_EXTENSION = "rubybreaker.rb"
83
+
84
+ private
85
+
86
+ # This method determines if RubyBreaker is running as a task.
87
+ def self.running_as_task?(); return $__rubybreaker_task != nil end
88
+
89
+ # This method returns the task currently being run.
90
+ def self.task(); return $__rubybreaker_task end
91
91
 
92
- # If this was a library mode run, exit now.
93
- return if OPTIONS[:mode] == :lib
92
+ # This method loads the IO file by loading it.
93
+ def self.load_input(fname)
94
+ return fname
95
+ eval "load \"#{fname}\"", TOPLEVEL_BINDING
96
+ RubyBreaker.verbose("RubyBreaker input file #{fname} is loaded")
97
+ end
98
+
99
+ # This method will generate the output to the given filename.
100
+ def self.output(fname)
101
+
102
+ RubyBreaker.verbose("Generating type documentation")
94
103
 
104
+ code = ""
105
+
106
+ # Document each module that was monitored.
107
+ INSTALLED.each { |mod|
108
+ str = Runtime::TypeSigUnparser.unparse(mod)
109
+ code << str
110
+ print str if OPTIONS[:stdout] # display on the screen if requested
111
+ }
112
+
113
+ if fname && OPTIONS[:save_output]
114
+ # Check if the file already exists--that is, if it was used for input
115
+ io_exist = File.exists?(fname)
116
+ RubyBreaker.verbose("Saving it to #{fname}")
95
117
  # Append the result to the input file (or create a new file)
96
- open(OPTIONS[:io_file],"a") do |f|
97
- unless io_exist
98
- f.puts "# This file is auto-generated by RubyBreaker"
99
- f.puts "require \"rubybreaker\""
118
+ fmode = OPTIONS[:append] ? "a" : "w"
119
+ open(fname, fmode) do |f|
120
+ # When append, do not write the header
121
+ unless OPTIONS[:append]
122
+ f.puts "# This file is auto-generated by RubyBreaker"
100
123
  end
124
+ # But time stamp always
125
+ f.puts "# Last modified: #{Time.now}"
126
+ f.puts "require \"rubybreaker\"" unless OPTIONS[:append]
101
127
  f.print code
102
128
  end
129
+ end
103
130
 
104
- RubyBreaker.verbose("Done generating type documentation")
131
+ RubyBreaker.verbose("Done generating type documentation")
132
+ end
133
+
134
+ # This method finds the IO file for this run. It is either specified in
135
+ # io-file option or using the program name or the task name.
136
+ def self.io_file(prog_or_task)
137
+ if OPTIONS[:io_file]
138
+ fname = OPTIONS[:io_file]
139
+ elsif prog_or_task
140
+ fname = "#{File.basename(prog_or_task.to_s, ".rb")}.#{IO_EXTENSION}"
105
141
  end
142
+ return nil unless fname
143
+ fname = File.absolute_path(fname)
144
+ return fname
145
+ end
106
146
 
107
- # This method will run do things in the following order:
108
- #
109
- # * Checks to see if the user program and an input file exists
110
- # * Loads the documentation for Ruby Core Library (TODO)
111
- # * Reads the input type documentation if any
112
- # * Reads (require's) the user program
113
- #
114
- def self.run()
115
-
116
- RubyBreaker.setup_logger()
117
- RubyBreaker.verbose("Running RubyBreaker")
118
-
119
- # First, take care of the program file.
120
- argv0 = OPTIONS[:file]
121
- prog_file = argv0
122
- prog_file = File.expand_path(prog_file)
123
-
124
- # It is ok to omit .rb extension. So try to see if prog_file.rb exists
125
- if !File.exist?(prog_file) && !File.extname(prog_file) == ".rb"
126
- prog_file = "#{prog_file}.rb"
127
- end
128
-
129
- if !File.exist?(prog_file)
130
- fatal("#{argv0} is an invalid file.")
131
- exit(1)
132
- end
147
+ public
148
+
149
+ # This method runs RubyBreaker for a particular test case (class). This
150
+ # is a bit different from running RubyBreaker as a shell program.
151
+ def self.run(*mods)
152
+ RubyBreaker.setup_logger() unless RubyBreaker.defined_logger?()
153
+
154
+ # Task based run should use the rubybreaker options same as in shell
155
+ # mode. So, parse the options first.
156
+ if self.running_as_task?() # running in task mode
157
+ RubyBreaker.verbose("Running RubyBreaker within a testcase")
158
+ task = self.task
159
+ OPTION_PARSER.parse(*task[:rubybreaker_opts])
160
+ Runtime.breakable(*task[:breakable])
161
+ task_name = task[:name]
162
+ RubyBreaker.verbose("Done reading task information")
163
+ io_file = self.io_file(task_name)
164
+ elsif OPTIONS[:prog_file] # running in shell mode
165
+ Runtime.breakable(*mods)
166
+ io_file = self.io_file(OPTIONS[:prog_file])
167
+ else
168
+ # Otherwise, assume there are no explicit IO files.
169
+ end
170
+ self.load_input(io_file)
133
171
 
134
- # Then, input/output file if specified
135
- if !OPTIONS[:io_file] || OPTIONS[:io_file].empty?
136
- OPTIONS[:io_file] = "#{File.basename(argv0, ".rb")}.#{EXTENSION}"
137
- end
138
- OPTIONS[:io_file] = File.absolute_path(OPTIONS[:io_file])
172
+ # The following is deprecated but doing this for backward compatibility
173
+ Runtime.instrument()
139
174
 
140
- if OPTIONS[:rubylib]
141
- RubyBreaker.verbose("Loading RubyBreaker's Ruby Core Library documentation")
142
- # Load the core library type documentation
143
- eval("require \"rubybreaker/rubylib\"", TOPLEVEL_BINDING)
144
- end
175
+ # At the end, we WILL generate an output of the type information.
176
+ at_exit { self.output(io_file) }
177
+ end
178
+
179
+ end
145
180
 
146
- # Read the input file first (as it might contain type documentation
147
- # already)
148
- Main.input()
181
+ # This method is available by default.
182
+ module Kernel
149
183
 
150
- # Finally, require the program file! Let it run! Wheeee!
151
- eval("require '#{prog_file}'", TOPLEVEL_BINDING)
184
+ def typesig(str)
185
+ _TypeDefs = RubyBreaker::TypeDefs
152
186
 
153
- RubyBreaker.verbose("Done running the input program")
187
+ # This MUST BE set for self type to work in type signatures.
188
+ _TypeDefs::SelfType.set_self(self)
154
189
 
155
- end
190
+ t = RubyBreaker::Runtime::TypeSigParser.parse(str)
191
+ t_map = RubyBreaker::Runtime::TYPE_MAP[self]
156
192
 
157
- end
193
+ # If the type map doesn't exist, create it on the fly. Now this module
194
+ # is broken!
195
+ if !t_map
196
+ t_map = {}
197
+ RubyBreaker::Runtime::TYPE_MAP[self] = t_map
198
+ end
158
199
 
159
- # This is the manual indicator for the program entry point. It simply
160
- # redirects to the monitor setup code.
161
- def self.monitor()
162
- Main.setup()
200
+ meth_type = t_map[t.meth_name]
201
+ if meth_type
202
+ if meth_type.instance_of?(_TypeDefs::MethodListType)
203
+ meth_type.types << t
204
+ else
205
+ # then promote it to a method list type
206
+ t_map[t.meth_name] = _TypeDefs::MethodListType.new([meth_type, t])
207
+ end
208
+ else
209
+ t_map[t.meth_name] = t
210
+ end
211
+ return t
163
212
  end
164
-
165
213
  end
166
214
 
@@ -3,18 +3,19 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedBothBrokenBreakableTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A
9
- include RubyBreaker::Breakable
10
- include RubyBreaker::Broken
8
+ # include RubyBreaker::Breakable
11
9
  typesig("foo(fixnum[to_s]) -> string")
12
10
  def foo(x); x.to_s end
13
11
  def bar(x); x.to_sym end
14
12
  end
15
13
 
14
+ def setup
15
+ RubyBreaker.breakable(A)
16
+ end
17
+
16
18
  def test_both_broken_and_breakable
17
- # A.new.foo(1)
18
19
  A.new.bar("abc")
19
20
  a_foo_meth_type = Runtime::Inspector.inspect_meth(A, :foo)
20
21
  a_bar_meth_type = Runtime::Inspector.inspect_meth(A, :bar)
@@ -3,21 +3,22 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedClassMethodsTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A
9
- include RubyBreaker::Breakable
10
8
  def self.foo(x); x.to_s end
11
9
  end
12
10
 
13
11
  class B
14
- include RubyBreaker::Broken
15
12
  class << self
16
13
  typesig("bar(fixnum[to_s]) -> string")
17
14
  def bar(x); x.to_s end
18
15
  end
19
16
  end
20
17
 
18
+ def setup()
19
+ RubyBreaker.breakable(A, B)
20
+ end
21
+
21
22
  def test_class_methods
22
23
  A.foo(1)
23
24
  a_foo_meth_type = Runtime::Inspector.inspect_class_meth(A, :foo)
@@ -3,19 +3,20 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedInheritBrokenTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A
9
- include RubyBreaker::Broken
10
8
  typesig("foo(fixnum[to_s]) -> string")
11
9
  def foo(x); x.to_s end
12
10
  end
13
11
 
14
12
  class B < A
15
- include RubyBreaker::Breakable
16
13
  def bar(x); foo(x) end
17
14
  end
18
15
 
16
+ def setup()
17
+ RubyBreaker.breakable(B)
18
+ end
19
+
19
20
  def test_both
20
21
  b = B.new
21
22
  b.bar(1)
@@ -3,16 +3,16 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedMethodMissingTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A
9
- include RubyBreaker::Breakable
10
-
11
8
  def method_missing(mname, *args, &blk)
12
9
  method_name = mname.to_s
13
10
  return method_name + "_" + args.join("_")
14
11
  end
15
-
12
+ end
13
+
14
+ def setup()
15
+ RubyBreaker.breakable(A)
16
16
  end
17
17
 
18
18
  # TODO: This must be fixed once variable length argument type is supported
@@ -3,7 +3,6 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedNamespaceTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A < String
9
8
  class C < String
@@ -17,12 +16,15 @@ class IntegratedNamespaceTest < Test::Unit::TestCase
17
16
  end
18
17
 
19
18
  class B
20
- include RubyBreaker::Breakable
21
19
  def foo(x); x.to_s end
22
20
  def bar(x); x.to_s end
23
21
  def baz(x); x.to_s end
24
22
  end
25
23
 
24
+ def setup()
25
+ RubyBreaker.breakable(B)
26
+ end
27
+
26
28
  def test_namspace_b_foo
27
29
  a = A.new
28
30
  b = B.new
@@ -3,10 +3,8 @@ require_relative "../../lib/rubybreaker"
3
3
 
4
4
  class IntegratedSimpleTest < Test::Unit::TestCase
5
5
  include RubyBreaker
6
- include RubyBreaker::TestCase
7
6
 
8
7
  class A
9
- include RubyBreaker::Breakable
10
8
 
11
9
  def foo(x)
12
10
  x.to_s
@@ -33,12 +31,15 @@ class IntegratedSimpleTest < Test::Unit::TestCase
33
31
  end
34
32
 
35
33
  class B
36
- include RubyBreaker::Broken
37
34
  typesig("baz(string[size], true_class) -> fixnum")
38
35
  typesig("baz(string[to_s], false_class) -> string")
39
36
  def baz(x,b); end
40
37
  end
41
38
 
39
+ def setup()
40
+ RubyBreaker.breakable(A)
41
+ end
42
+
42
43
  def test_simple1_a_foo
43
44
  a = A.new
44
45
  a.foo("test_simple1 >> string")
@@ -16,6 +16,16 @@ class ObjectWrapperTest < Test::Unit::TestCase
16
16
  x.to_s
17
17
  end
18
18
 
19
+ def baz(x)
20
+ x.send(:foo,1)
21
+ end
22
+
23
+ class A
24
+ def foo(x)
25
+ x.to_s
26
+ end
27
+ end
28
+
19
29
  def test_empty()
20
30
  x = 42
21
31
  wrapped_x = Runtime::ObjectWrapper.new(x)
@@ -24,28 +34,37 @@ class ObjectWrapperTest < Test::Unit::TestCase
24
34
  assert_equal("fixnum[]",str)
25
35
  end
26
36
 
27
- def test_simple_foo()
37
+ def setup
38
+ Runtime::GLOBAL_MONITOR_SWITCH.turn_on()
39
+ end
40
+
41
+ def test_foo()
28
42
  x = 42
29
43
  wrapped_x = Runtime::ObjectWrapper.new(x)
30
- Runtime::GLOBAL_MONITOR_SWITCH.turn_on()
31
44
  foo(wrapped_x)
32
- Runtime::GLOBAL_MONITOR_SWITCH.turn_off()
33
45
  type = wrapped_x.__rubybreaker_type()
34
46
  str = TypeUnparser.unparse(type)
35
47
  assert_equal("fixnum[to_f, to_s]",str)
36
48
  end
37
49
 
38
- def test_simple_bar()
50
+ def test_bar()
39
51
  x = 42
40
52
  wrapped_x = Runtime::ObjectWrapper.new(x)
41
- Runtime::GLOBAL_MONITOR_SWITCH.turn_on()
42
53
  bar(wrapped_x)
43
- Runtime::GLOBAL_MONITOR_SWITCH.turn_off()
44
54
  type = wrapped_x.__rubybreaker_type()
45
55
  str = TypeUnparser.unparse(type)
46
56
  assert_equal("fixnum[to_f, to_s]",str)
47
57
  end
48
58
 
59
+ def test_baz()
60
+ x = A.new
61
+ wrapped_x = Runtime::ObjectWrapper.new(x)
62
+ baz(wrapped_x)
63
+ type = wrapped_x.__rubybreaker_type()
64
+ str = TypeUnparser.unparse(type)
65
+ assert_equal("object_wrapper_test/a[foo]", str)
66
+ end
67
+
49
68
  def test_object_id()
50
69
  x = 42
51
70
  wrapped_x = Runtime::ObjectWrapper.new(x)
@@ -9,7 +9,6 @@ class TypeSigTest < Test::Unit::TestCase
9
9
  include RubyBreaker
10
10
 
11
11
  class A
12
- include RubyBreaker::Broken
13
12
  typesig("foo(fixnum) -> fixnum")
14
13
  typesig("bar(fixnum) -> self")
15
14
  end
@@ -0,0 +1,10 @@
1
+ # Below classes are used for internal testing
2
+
3
+ class SampleClassA
4
+ def foo(x); x.to_s end
5
+ end
6
+
7
+ class SampleClassB
8
+ def foo(x); x.to_s end
9
+ end
10
+
@@ -0,0 +1,25 @@
1
+ require "test/unit"
2
+ require_relative "sample"
3
+ require "rubybreaker"
4
+
5
+ class SampleClassB # re-opening
6
+ typesig("foo(fixnum[to_s]) -> string")
7
+ end
8
+
9
+ class RubyBreakerTestTaskTest < Test::Unit::TestCase
10
+
11
+ def test_breakable()
12
+ SampleClassA.new.foo(2)
13
+ t = RubyBreaker::Runtime::Inspector.inspect_meth(SampleClassA, :foo)
14
+ str = t.unparse()
15
+ assert_equal("foo(fixnum[to_s]) -> string", str)
16
+ end
17
+
18
+ def test_broken()
19
+ t = RubyBreaker::Runtime::Inspector.inspect_meth(SampleClassB, :foo)
20
+ str = t.unparse()
21
+ assert_equal("foo(fixnum[to_s]) -> string", str)
22
+ end
23
+
24
+ end
25
+
data/test/ts_rspec.rb CHANGED
@@ -2,30 +2,36 @@ require "rspec"
2
2
  require_relative "../lib/rubybreaker"
3
3
 
4
4
  class RSpecTestA
5
- include RubyBreaker::Breakable
6
5
  def foo(x); x.to_s end
7
6
  end
8
7
 
9
8
  class RSpecTestB
10
- include RubyBreaker::Broken
11
9
  typesig("foo(fixnum[to_s]) -> string")
12
10
  end
13
11
 
14
- describe RSpecTestA do
15
- it "should return a string of number" do
16
- a = RSpecTestA.new
17
- a.foo(1)
18
- a_foo_type = RubyBreaker::Runtime::Inspector.inspect_meth(RSpecTestA, :foo)
19
- str = a_foo_type.unparse()
20
- str.should == "foo(fixnum[to_s]) -> string"
12
+ describe "RSpec Test" do
13
+
14
+ before do
15
+ RubyBreaker.breakable(RSpecTestA)
21
16
  end
22
- end
23
17
 
24
- describe RSpecTestB do
25
- it "should return the documented type of B#foo" do
26
- b_foo_type = RubyBreaker::Runtime::Inspector.inspect_meth(RSpecTestB, :foo)
27
- str = b_foo_type.unparse()
28
- str.should == "foo(fixnum[to_s]) -> string"
18
+ describe RSpecTestA do
19
+ it "should return a string of number" do
20
+ a = RSpecTestA.new
21
+ a.foo(1)
22
+ a_foo_type = RubyBreaker::Runtime::Inspector.inspect_meth(RSpecTestA, :foo)
23
+ str = a_foo_type.unparse()
24
+ str.should == "foo(fixnum[to_s]) -> string"
25
+ end
29
26
  end
27
+
28
+ describe RSpecTestB do
29
+ it "should return the documented type of B#foo" do
30
+ b_foo_type = RubyBreaker::Runtime::Inspector.inspect_meth(RSpecTestB, :foo)
31
+ str = b_foo_type.unparse()
32
+ str.should == "foo(fixnum[to_s]) -> string"
33
+ end
34
+ end
35
+
30
36
  end
31
37
 
@@ -8,7 +8,6 @@ class TypingTest < Test::Unit::TestCase
8
8
  include RubyBreaker
9
9
 
10
10
  class A
11
- include RubyBreaker::Broken
12
11
  typesig("foo(fixnum) -> fixnum")
13
12
  typesig("bar(fixnum) {|fixnum| -> string} -> string")
14
13
  typesig("baz(fixnum, string?) -> fixnum")
@@ -100,14 +99,14 @@ class TypingTest < Test::Unit::TestCase
100
99
  assert(t1.subtype_of?(t2), msg(t1, t2))
101
100
  assert(t2.subtype_of?(t1), msg(t1, t2))
102
101
  # XXX: The following assert will succeed because Fixnum and String are
103
- # not Broken at this point.
102
+ # not "broken" at this point.
104
103
  assert(t1.subtype_of?(t3), msg(t1, t3, true))
105
104
  end
106
105
 
107
106
  def test_duck_fusion_types()
108
107
  t1 = DuckType.new([:to_s, :to_f])
109
108
  t2 = FusionType.new(NominalType.new(Fixnum), [:to_f, :to_s])
110
- # Again, this works because Fixnum is not Broken yet
109
+ # Again, this works because Fixnum is not "broken" yet
111
110
  assert(t1.subtype_of?(t2), msg(t1, t2))
112
111
  assert(t2.subtype_of?(t1), msg(t1, t2))
113
112
  end