rubybreaker 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/NEWS +4 -0
  2. data/README.md +33 -19
  3. data/Rakefile +31 -13
  4. data/TODO +6 -4
  5. data/VERSION +1 -1
  6. data/bin/rubybreaker +0 -1
  7. data/lib/rubybreaker/debug/debug.rb +1 -1
  8. data/lib/rubybreaker/runtime/typesig_unparser.rb +96 -0
  9. data/lib/rubybreaker/runtime.rb +1 -0
  10. data/lib/rubybreaker/test/rspec.rb +15 -0
  11. data/lib/rubybreaker/test/testcase.rb +4 -4
  12. data/lib/rubybreaker/test.rb +1 -0
  13. data/lib/rubybreaker/type/type_grammar.treetop +5 -4
  14. data/lib/rubybreaker/type/type_unparser.rb +69 -25
  15. data/lib/rubybreaker.rb +9 -77
  16. data/test/integrated/tc_namespace.rb +56 -0
  17. data/test/ts_integrated.rb +1 -0
  18. data/test/ts_rspec.rb +31 -0
  19. data/test/ts_type.rb +2 -0
  20. data/test/type/tc_camelize.rb +24 -0
  21. data/test/type/tc_namespace.rb +25 -0
  22. data/test/type/tc_unparser.rb +31 -32
  23. data/webpage/index.html +34 -19
  24. data/webpage/rdoc/Object.html +308 -0
  25. data/webpage/rdoc/RubyBreaker/Breakable.html +5 -1
  26. data/webpage/rdoc/RubyBreaker/Broken/BrokenEigen.html +5 -1
  27. data/webpage/rdoc/RubyBreaker/Broken.html +5 -1
  28. data/webpage/rdoc/RubyBreaker/Context.html +5 -1
  29. data/webpage/rdoc/RubyBreaker/Errors/InternalError.html +4 -0
  30. data/webpage/rdoc/RubyBreaker/Errors/InvalidSubtypeCheck.html +4 -0
  31. data/webpage/rdoc/RubyBreaker/Errors/InvalidTypeConstruction.html +4 -0
  32. data/webpage/rdoc/RubyBreaker/Errors/SubtypeFailure.html +4 -0
  33. data/webpage/rdoc/RubyBreaker/Errors/TypeError.html +4 -0
  34. data/webpage/rdoc/RubyBreaker/Errors/UserError.html +4 -0
  35. data/webpage/rdoc/RubyBreaker/Errors.html +4 -0
  36. data/webpage/rdoc/RubyBreaker/Main.html +17 -132
  37. data/webpage/rdoc/RubyBreaker/ObjectPosition.html +5 -1
  38. data/webpage/rdoc/RubyBreaker/Position.html +5 -1
  39. data/webpage/rdoc/RubyBreaker/RubyTypeUtils.html +4 -0
  40. data/webpage/rdoc/RubyBreaker/Runtime/Inspector.html +4 -0
  41. data/webpage/rdoc/RubyBreaker/Runtime/MethodInfo.html +5 -1
  42. data/webpage/rdoc/RubyBreaker/Runtime/Monitor.html +5 -1
  43. data/webpage/rdoc/RubyBreaker/Runtime/MonitorInstaller.html +4 -0
  44. data/webpage/rdoc/RubyBreaker/Runtime/MonitorSwitch.html +5 -1
  45. data/webpage/rdoc/RubyBreaker/Runtime/MonitorUtils.html +4 -0
  46. data/webpage/rdoc/RubyBreaker/Runtime/ObjectWrapper.html +4 -0
  47. data/webpage/rdoc/RubyBreaker/Runtime/Pluggable.html +4 -0
  48. data/webpage/rdoc/RubyBreaker/Runtime/TypePlaceholder.html +5 -1
  49. data/webpage/rdoc/RubyBreaker/Runtime/TypeSigParser.html +4 -0
  50. data/webpage/rdoc/RubyBreaker/Runtime/TypeSystem.html +5 -1
  51. data/webpage/rdoc/RubyBreaker/Runtime/TypesigUnparser.html +404 -0
  52. data/webpage/rdoc/RubyBreaker/Runtime.html +5 -0
  53. data/webpage/rdoc/RubyBreaker/TestCase.html +47 -43
  54. data/webpage/rdoc/RubyBreaker/TypeComparer.html +4 -0
  55. data/webpage/rdoc/RubyBreaker/TypeDefs/AnyType.html +4 -0
  56. data/webpage/rdoc/RubyBreaker/TypeDefs/BlockType.html +4 -0
  57. data/webpage/rdoc/RubyBreaker/TypeDefs/DuckType.html +4 -0
  58. data/webpage/rdoc/RubyBreaker/TypeDefs/FusionType.html +4 -0
  59. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodListType.html +4 -0
  60. data/webpage/rdoc/RubyBreaker/TypeDefs/MethodType.html +4 -0
  61. data/webpage/rdoc/RubyBreaker/TypeDefs/NilType.html +4 -0
  62. data/webpage/rdoc/RubyBreaker/TypeDefs/NominalType.html +4 -0
  63. data/webpage/rdoc/RubyBreaker/TypeDefs/OptionalType.html +4 -0
  64. data/webpage/rdoc/RubyBreaker/TypeDefs/OrType.html +4 -0
  65. data/webpage/rdoc/RubyBreaker/TypeDefs/SelfType.html +4 -0
  66. data/webpage/rdoc/RubyBreaker/TypeDefs/Type.html +11 -6
  67. data/webpage/rdoc/RubyBreaker/TypeDefs/VarLengthType.html +4 -0
  68. data/webpage/rdoc/RubyBreaker/TypeDefs.html +4 -0
  69. data/webpage/rdoc/RubyBreaker/TypeUnparser.html +15 -7
  70. data/webpage/rdoc/RubyBreaker/Typing.html +4 -0
  71. data/webpage/rdoc/RubyBreaker/Util.html +4 -0
  72. data/webpage/rdoc/RubyBreaker.html +6 -6
  73. data/webpage/rdoc/created.rid +9 -7
  74. data/webpage/rdoc/index.html +4 -0
  75. data/webpage/rdoc/js/search_index.js +1 -1
  76. data/webpage/rdoc/table_of_contents.html +36 -24
  77. metadata +13 -7
data/lib/rubybreaker.rb CHANGED
@@ -30,9 +30,6 @@ module RubyBreaker
30
30
  # monitor.
31
31
  INSTALLED = []
32
32
 
33
- # This array lists monitored modules/classes that are outputed.
34
- DOCUMENTED = []
35
-
36
33
  # Extension used by RubyBreaker for output/input
37
34
  EXTENSION = "rubybreaker"
38
35
 
@@ -75,71 +72,6 @@ module RubyBreaker
75
72
  eval "load \"#{OPTIONS[:io_file]}\"", TOPLEVEL_BINDING
76
73
  end
77
74
 
78
- # Pretty prints type information for methods
79
- def self.pp_methods(pp, meth_type_map)
80
- meth_type_map.each { |meth_name, meth_type|
81
- case meth_type
82
- when MethodType
83
- pp.breakable()
84
- pp.text("typesig(\"")
85
- TypeUnparser.unparse_pp(pp,meth_type)
86
- pp.text("\")")
87
- when MethodListType
88
- meth_type.types.each { |real_meth_type|
89
- pp.breakable()
90
- pp.text("typesig(\"")
91
- TypeUnparser.unparse_pp(pp,real_meth_type)
92
- pp.text("\")")
93
- }
94
- else
95
- # Can't happen
96
- end
97
- }
98
- end
99
-
100
- # Pretty prints type information for the module/class
101
- def self.pp_module(pp, mod)
102
- # Skip it if we already have seen it
103
- return if DOCUMENTED.include?(mod) || mod.to_s[0..1] == "#<"
104
-
105
- # Remember that we have documented this module/class
106
- DOCUMENTED << mod
107
-
108
- # Get the method type mapping
109
- meth_type_map = Inspector.inspect_all(mod)
110
-
111
- # Check if this module is a class
112
- keyword = mod.instance_of?(Class) ? "class" : "module"
113
-
114
- pp.text("#{keyword} #{mod.to_s}", 80)
115
- pp.nest(2) do
116
- pp.breakable("")
117
- pp.text("include RubyBreaker::Broken", 80)
118
-
119
- # See if there is any class method to show
120
- eigen = Runtime.eigen_class(mod)
121
-
122
- if !DOCUMENTED.include?(eigen)
123
- DOCUMENTED << eigen
124
- eigen_meth_type_map = Inspector.inspect_all(eigen)
125
- if eigen_meth_type_map.size > 0
126
- pp.breakable()
127
- pp.text("class << self", 80)
128
- pp.nest(2) do
129
- self.pp_methods(pp, eigen_meth_type_map)
130
- end
131
- pp.breakable()
132
- pp.text("end", 80)
133
- end
134
- end
135
- self.pp_methods(pp, meth_type_map)
136
-
137
- end
138
- pp.breakable()
139
- pp.text("end",80)
140
- pp.breakable()
141
- end
142
-
143
75
  # This method will generate the output.
144
76
  def self.output()
145
77
 
@@ -147,15 +79,15 @@ module RubyBreaker
147
79
 
148
80
  io_exist = OPTIONS[:io_file] && File.exist?(OPTIONS[:io_file])
149
81
 
150
- str = ""
151
- pp = PrettyPrint.new(str)
152
-
82
+ code = ""
153
83
  # Document each module that was monitored
154
- INSTALLED.each { |mod| self.pp_module(pp, mod) }
155
- pp.flush
156
-
157
- # First, display the result on the stdout if set
158
- print str if OPTIONS[:stdout]
84
+ INSTALLED.each { |mod|
85
+ str = Runtime::TypesigUnparser.unparse(mod)
86
+ code << str
87
+ if OPTIONS[:mode] == :lib
88
+ print str
89
+ end
90
+ }
159
91
 
160
92
  # If this was a library mode run, exit now.
161
93
  return if OPTIONS[:mode] == :lib
@@ -166,7 +98,7 @@ module RubyBreaker
166
98
  f.puts "# This file is auto-generated by RubyBreaker"
167
99
  f.puts "require \"rubybreaker\""
168
100
  end
169
- f.puts str
101
+ f.print code
170
102
  end
171
103
 
172
104
  RubyBreaker.verbose("Done generating type documentation")
@@ -0,0 +1,56 @@
1
+ require "test/unit"
2
+ require_relative "../../lib/rubybreaker"
3
+
4
+ class IntegratedNamespaceTest < Test::Unit::TestCase
5
+ include RubyBreaker
6
+ include RubyBreaker::TestCase
7
+
8
+ class A < String
9
+ class C < String
10
+ class D < String
11
+ class E < String
12
+ end
13
+ end
14
+ class F
15
+ end
16
+ end
17
+ end
18
+
19
+ class B
20
+ include RubyBreaker::Breakable
21
+ def foo(x); x.to_s end
22
+ def bar(x); x.to_s end
23
+ def baz(x); x.to_s end
24
+ end
25
+
26
+ def test_namspace_b_foo
27
+ a = A.new
28
+ b = B.new
29
+ b.foo(a)
30
+ meth_type = Runtime::Inspector.inspect_meth(B, :foo)
31
+ str = RubyBreaker::TypeUnparser.unparse(meth_type)
32
+ # puts str
33
+ assert_equal("foo(integrated_namespace_test/a[to_s]) -> string", str, "B#foo failed.")
34
+ end
35
+
36
+ def test_namspace_b_foo_nested
37
+ a = A::C.new
38
+ b = B.new
39
+ b.bar(a)
40
+ meth_type = Runtime::Inspector.inspect_meth(B, :bar)
41
+ str = RubyBreaker::TypeUnparser.unparse(meth_type)
42
+ # puts str
43
+ assert_equal("bar(integrated_namespace_test/a/c[to_s]) -> string", str, "B#bar failed.")
44
+ end
45
+
46
+ def test_namespace_e_baz
47
+ e = A::C::D::E.new
48
+ b = B.new
49
+ b.baz(e)
50
+ meth_type = Runtime::Inspector.inspect_meth(B, :baz)
51
+ str = meth_type.unparse(:namespace => A::C::F)
52
+ assert_equal("baz(d/e[to_s]) -> string", str, "B#baz failed.")
53
+ end
54
+
55
+ end
56
+
@@ -5,3 +5,4 @@ require_relative "integrated/tc_simple1"
5
5
  require_relative "integrated/tc_inherit_broken"
6
6
  require_relative "integrated/tc_class_methods"
7
7
  require_relative "integrated/tc_both_broken_breakable"
8
+ require_relative "integrated/tc_namespace"
data/test/ts_rspec.rb ADDED
@@ -0,0 +1,31 @@
1
+ require "rspec"
2
+ require_relative "../lib/rubybreaker"
3
+
4
+ class RSpecTestA
5
+ include RubyBreaker::Breakable
6
+ def foo(x); x.to_s end
7
+ end
8
+
9
+ class RSpecTestB
10
+ include RubyBreaker::Broken
11
+ typesig("foo(fixnum[to_s]) -> string")
12
+ end
13
+
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"
21
+ end
22
+ end
23
+
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"
29
+ end
30
+ end
31
+
data/test/ts_type.rb CHANGED
@@ -3,3 +3,5 @@ require "test/unit"
3
3
  require_relative "type/tc_comparer"
4
4
  require_relative "type/tc_parser"
5
5
  require_relative "type/tc_unparser"
6
+ require_relative "type/tc_camelize"
7
+ require_relative "type/tc_namespace"
@@ -0,0 +1,24 @@
1
+ # This test verifies type unparser for RubyBreaker types.
2
+ require "test/unit"
3
+ require_relative "../../lib/rubybreaker/type"
4
+
5
+ class UnparserCamelizeTest < Test::Unit::TestCase
6
+
7
+ include RubyBreaker
8
+
9
+ class CamelizedClassName; end
10
+
11
+ def test_camelize_type()
12
+ t1 = NominalType.new(CamelizedClassName)
13
+ str1 = t1.unparse({:style => :camelize, :namespace => UnparserCamelizeTest})
14
+ # puts str1
15
+ assert_equal("CamelizedClassName",str1.strip())
16
+ end
17
+
18
+ def test_camelize_no_namespace_type()
19
+ t1 = NominalType.new(CamelizedClassName)
20
+ str1 = t1.unparse({:style => :camelize, :namespace => UnparserCamelizeTest})
21
+ # puts str1
22
+ assert_equal("CamelizedClassName",str1.strip())
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # This test verifies handling of namespace in parsing types.
2
+ require "test/unit"
3
+ require_relative "../../lib/rubybreaker/type"
4
+
5
+ class TypeNamespaceTest < Test::Unit::TestCase
6
+
7
+ include RubyBreaker
8
+
9
+ class A
10
+ end
11
+
12
+ def setup
13
+ @parser = Runtime::TypeSigParser::PARSER
14
+ end
15
+
16
+ def teardown
17
+ end
18
+
19
+ def test_namespace_1
20
+ t1 = @parser.parse("foo(type_namespace_test/a[to_s]) -> string").value
21
+ str = t1.unparse(:style => :camelize)
22
+ assert_equal("foo(TypeNamespaceTest::A[to_s]) -> String", str)
23
+ end
24
+
25
+ end
@@ -1,8 +1,7 @@
1
1
  # This test verifies type unparser for RubyBreaker types.
2
2
 
3
- dir = File.dirname(__FILE__)
4
3
  require "test/unit"
5
- require "#{dir}/../../lib/rubybreaker/type"
4
+ require_relative "../../lib/rubybreaker/type"
6
5
 
7
6
  class UnparserTest < Test::Unit::TestCase
8
7
 
@@ -30,14 +29,14 @@ class UnparserTest < Test::Unit::TestCase
30
29
 
31
30
  def test_nominal_type()
32
31
  t1 = NominalType.new(A)
33
- str1 = TypeUnparser.unparse(t1)
32
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
34
33
  # puts str1
35
34
  assert_equal("a",str1)
36
35
  end
37
36
 
38
37
  def test_self_type()
39
38
  t1 = SelfType.new()
40
- str1 = TypeUnparser.unparse(t1)
39
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
41
40
  # puts str1
42
41
  assert_equal("self", str1)
43
42
  end
@@ -45,7 +44,7 @@ class UnparserTest < Test::Unit::TestCase
45
44
  def test_opt_type()
46
45
  t1 = NominalType.new(A)
47
46
  t2 = OptionalType.new(t1)
48
- str2 = TypeUnparser.unparse(t2)
47
+ str2 = TypeUnparser.unparse(t2, :namespace => UnparserTest)
49
48
  # puts str1
50
49
  assert_equal("a?",str2)
51
50
  end
@@ -55,7 +54,7 @@ class UnparserTest < Test::Unit::TestCase
55
54
  t2 = NominalType.new(B)
56
55
  t3 = OrType.new([t1, t2])
57
56
  t4 = OptionalType.new(t3)
58
- str4 = TypeUnparser.unparse(t4)
57
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
59
58
  # puts str1
60
59
  assert_equal("(a || b)?",str4)
61
60
  end
@@ -63,15 +62,15 @@ class UnparserTest < Test::Unit::TestCase
63
62
  def test_star_type()
64
63
  t1 = NominalType.new(A)
65
64
  t2 = VarLengthType.new(t1)
66
- str2 = TypeUnparser.unparse(t2)
65
+ str2 = TypeUnparser.unparse(t2, :namespace => UnparserTest)
67
66
  # puts str1
68
- assert_equal("a*",str2)
67
+ assert_equal("a*", str2)
69
68
  end
70
69
 
71
70
  def test_star_duck_type()
72
71
  t1 = DuckType.new([:foo, :bar])
73
72
  t2 = VarLengthType.new(t1)
74
- str2 = TypeUnparser.unparse(t2)
73
+ str2 = TypeUnparser.unparse(t2, :namespace => UnparserTest)
75
74
  # puts str1
76
75
  assert_equal("[bar, foo]*",str2)
77
76
  end
@@ -79,7 +78,7 @@ class UnparserTest < Test::Unit::TestCase
79
78
  def test_star_fusion_type()
80
79
  t1 = FusionType.new(NominalType.new(A), [:foo, :bar])
81
80
  t2 = VarLengthType.new(t1)
82
- str2 = TypeUnparser.unparse(t2)
81
+ str2 = TypeUnparser.unparse(t2, :namespace => UnparserTest)
83
82
  # puts str1
84
83
  assert_equal("a[bar, foo]*",str2)
85
84
  end
@@ -89,49 +88,49 @@ class UnparserTest < Test::Unit::TestCase
89
88
  t2 = NominalType.new(B)
90
89
  t3 = OrType.new([t1, t2])
91
90
  t4 = VarLengthType.new(t3)
92
- str4 = TypeUnparser.unparse(t4)
91
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
93
92
  # puts str1
94
93
  assert_equal("(a || b)*",str4)
95
94
  end
96
95
 
97
96
  def test_duck_type()
98
97
  t1 = DuckType.new(["+"])
99
- str1 = TypeUnparser.unparse(t1)
98
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
100
99
  # puts str1
101
100
  assert_equal("[+]",str1)
102
101
  end
103
102
 
104
103
  def test_duck_type_more_meths()
105
104
  t1 = DuckType.new(["+","foo","bar"])
106
- str1 = TypeUnparser.unparse(t1)
105
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
107
106
  #puts str1
108
107
  assert_equal("[+, bar, foo]",str1)
109
108
  end
110
109
 
111
110
  def test_duck_type_symbolic_meths()
112
111
  t1 = DuckType.new(["+","-","[]","[]="])
113
- str1 = TypeUnparser.unparse(t1)
112
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
114
113
  #puts str1
115
114
  assert_equal("[+, -, [], []=]",str1)
116
115
  end
117
116
 
118
117
  def test_fusion_type()
119
118
  t1 = FusionType.new(NominalType.new(A), ["+"])
120
- str1 = TypeUnparser.unparse(t1)
119
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
121
120
  # puts str1
122
121
  assert_equal("a[+]",str1)
123
122
  end
124
123
 
125
124
  def test_fusion_type_more_meths()
126
125
  t1 = FusionType.new(NominalType.new(A), ["+","foo","bar"])
127
- str1 = TypeUnparser.unparse(t1)
126
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
128
127
  # puts str1
129
128
  assert_equal("a[+, bar, foo]",str1)
130
129
  end
131
130
 
132
131
  def test_fusion_type_symbolic_meths()
133
132
  t1 = FusionType.new(NominalType.new(A), ["+","-","[]","[]="])
134
- str1 = TypeUnparser.unparse(t1)
133
+ str1 = TypeUnparser.unparse(t1, :namespace => UnparserTest)
135
134
  # puts str1
136
135
  assert_equal("a[+, -, [], []=]",str1)
137
136
  end
@@ -140,7 +139,7 @@ class UnparserTest < Test::Unit::TestCase
140
139
  t1 = NominalType.new(A)
141
140
  t2 = NominalType.new(B)
142
141
  t3 = OrType.new([t1,t2])
143
- str3 = TypeUnparser.unparse(t3)
142
+ str3 = TypeUnparser.unparse(t3, :namespace => UnparserTest)
144
143
  # puts str3
145
144
  assert_equal("a || b", str3)
146
145
  end
@@ -150,7 +149,7 @@ class UnparserTest < Test::Unit::TestCase
150
149
  t2 = NominalType.new(B)
151
150
  t3 = NominalType.new(C)
152
151
  t4 = OrType.new([t1,t2,t3])
153
- str4 = TypeUnparser.unparse(t4)
152
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
154
153
  # puts str3
155
154
  assert_equal("a || b || c", str4)
156
155
  end
@@ -159,7 +158,7 @@ class UnparserTest < Test::Unit::TestCase
159
158
  t1 = NominalType.new(A)
160
159
  t2 = NominalType.new(B)
161
160
  t3 = BlockType.new([t1],nil,t2)
162
- str3 = TypeUnparser.unparse(t3)
161
+ str3 = TypeUnparser.unparse(t3, :namespace => UnparserTest)
163
162
  # puts str3
164
163
  assert_equal("|a| -> b",str3)
165
164
  end
@@ -169,7 +168,7 @@ class UnparserTest < Test::Unit::TestCase
169
168
  t2 = NominalType.new(B)
170
169
  t3 = NominalType.new(C)
171
170
  t4 = BlockType.new([t1,t2],nil,t3)
172
- str4 = TypeUnparser.unparse(t4)
171
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
173
172
  # puts str3
174
173
  assert_equal("|a, b| -> c",str4)
175
174
  end
@@ -179,7 +178,7 @@ class UnparserTest < Test::Unit::TestCase
179
178
  t2 = NominalType.new(B)
180
179
  t3 = SelfType.new()
181
180
  t4 = BlockType.new([t1,t2],nil,t3)
182
- str4 = TypeUnparser.unparse(t4)
181
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
183
182
  # puts str3
184
183
  assert_equal("|a, b| -> self",str4)
185
184
  end
@@ -190,7 +189,7 @@ class UnparserTest < Test::Unit::TestCase
190
189
  t3 = NominalType.new(C)
191
190
  t4 = NominalType.new(D)
192
191
  t5 = BlockType.new([t1],BlockType.new([t2],nil,t3),t4)
193
- str5 = TypeUnparser.unparse(t5)
192
+ str5 = TypeUnparser.unparse(t5, :namespace => UnparserTest)
194
193
  # puts str5
195
194
  assert_equal("|a| {|b| -> c} -> d",str5)
196
195
  end
@@ -202,7 +201,7 @@ class UnparserTest < Test::Unit::TestCase
202
201
  t4 = NominalType.new(D)
203
202
  t5 = NominalType.new(E)
204
203
  t6 = BlockType.new([t1,t2],BlockType.new([t3],nil,t4),t5)
205
- str6 = TypeUnparser.unparse(t6)
204
+ str6 = TypeUnparser.unparse(t6, :namespace => UnparserTest)
206
205
  # puts str5
207
206
  assert_equal("|a, b| {|c| -> d} -> e",str6)
208
207
  end
@@ -214,7 +213,7 @@ class UnparserTest < Test::Unit::TestCase
214
213
  t4 = NominalType.new(D)
215
214
  t5 = NominalType.new(E)
216
215
  t6 = BlockType.new([OrType.new([t1,t2])],BlockType.new([t3],nil,t4),t5)
217
- str6 = TypeUnparser.unparse(t6)
216
+ str6 = TypeUnparser.unparse(t6, :namespace => UnparserTest)
218
217
  # puts str5
219
218
  assert_equal("|a || b| {|c| -> d} -> e",str6)
220
219
  end
@@ -223,7 +222,7 @@ class UnparserTest < Test::Unit::TestCase
223
222
  t1 = NominalType.new(A)
224
223
  t2 = NominalType.new(B)
225
224
  t3 = MethodType.new("m",[t1],nil,t2)
226
- str3 = TypeUnparser.unparse(t3)
225
+ str3 = TypeUnparser.unparse(t3, :namespace => UnparserTest)
227
226
  # puts str3
228
227
  assert_equal("m(a) -> b", str3)
229
228
  end
@@ -232,7 +231,7 @@ class UnparserTest < Test::Unit::TestCase
232
231
  t1 = NominalType.new(A)
233
232
  t2 = NominalType.new(B)
234
233
  t3 = MethodType.new("==",[t1],nil,t2)
235
- str3 = TypeUnparser.unparse(t3)
234
+ str3 = TypeUnparser.unparse(t3, :namespace => UnparserTest)
236
235
  # puts str3
237
236
  assert_equal("==(a) -> b", str3)
238
237
  end
@@ -242,7 +241,7 @@ class UnparserTest < Test::Unit::TestCase
242
241
  t2 = NominalType.new(B)
243
242
  t3 = NominalType.new(C)
244
243
  t4 = MethodType.new("m",[t1,t2],nil,t3)
245
- str4 = TypeUnparser.unparse(t4)
244
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
246
245
  # puts str3
247
246
  assert_equal("m(a, b) -> c", str4)
248
247
  end
@@ -252,7 +251,7 @@ class UnparserTest < Test::Unit::TestCase
252
251
  t2 = NominalType.new(B)
253
252
  t3 = SelfType.new()
254
253
  t4 = MethodType.new("m",[t1,t2],nil,t3)
255
- str4 = TypeUnparser.unparse(t4)
254
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
256
255
  # puts str3
257
256
  assert_equal("m(a, b) -> self", str4)
258
257
  end
@@ -262,7 +261,7 @@ class UnparserTest < Test::Unit::TestCase
262
261
  t2 = NominalType.new(B)
263
262
  t3 = NominalType.new(C)
264
263
  t4 = MethodType.new("m",[OrType.new([t1,t2])],nil,t3)
265
- str4 = TypeUnparser.unparse(t4)
264
+ str4 = TypeUnparser.unparse(t4, :namespace => UnparserTest)
266
265
  # puts str3
267
266
  assert_equal("m(a || b) -> c", str4)
268
267
  end
@@ -273,7 +272,7 @@ class UnparserTest < Test::Unit::TestCase
273
272
  t3 = NominalType.new(C)
274
273
  t4 = NominalType.new(D)
275
274
  t5 = MethodType.new("m",[t1],BlockType.new([t2],nil,t3),t4)
276
- str5 = TypeUnparser.unparse(t5)
275
+ str5 = TypeUnparser.unparse(t5, :namespace => UnparserTest)
277
276
  # puts str5
278
277
  assert_equal("m(a) {|b| -> c} -> d", str5)
279
278
  end
@@ -285,7 +284,7 @@ class UnparserTest < Test::Unit::TestCase
285
284
  t4 = NominalType.new(D)
286
285
  t5 = NominalType.new(E)
287
286
  t6 = MethodType.new("m",[t1,t2],BlockType.new([t3],nil,t4),t5)
288
- str6 = TypeUnparser.unparse(t6)
287
+ str6 = TypeUnparser.unparse(t6, :namespace => UnparserTest)
289
288
  # puts str5
290
289
  assert_equal("m(a, b) {|c| -> d} -> e", str6)
291
290
  end
data/webpage/index.html CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  <h1>Introduction</h1>
18
18
 
19
- <p>RubyBreaker is a dynamic type documentation tool written purely in Ruby. It
19
+ <p>RubyBreaker is a dynamic type documentation tool written in pure Ruby. It
20
20
  provides the framework for dynamically instrumenting a Ruby program to
21
21
  monitor objects during executions and document the observed type
22
22
  information. The type documentation generated by RubyBreaker is also an
@@ -27,7 +27,7 @@ program.</p>
27
27
  <p>The primary goal of RubyBreaker is to assign a type signature to every
28
28
  method in designated modules and classes. A type signature is written in
29
29
  the RubyBreaker Type Annotation Language which resembles the documentation
30
- style used in RubyDoc. Overall, this tool should help Ruby programmers
30
+ style used in Ruby API Doc. Overall, this tool should help Ruby programmers
31
31
  document their code more rigorously and effectively. Currently, manual
32
32
  modification of the user program is required to run RubyBreaker, but this is
33
33
  kept minimal.</p>
@@ -40,10 +40,9 @@ be found in <a href="rdoc/index.html">here</a>.</p>
40
40
  <h2>Limitations</h2>
41
41
 
42
42
  <ul>
43
- <li>It only works on toy Ruby programs so far :)</li>
44
43
  <li>Block argument cannot be auto-documented. (Inherent)</li>
45
44
  <li>Manual modification (minimal) of code is required.</li>
46
- <li>No parametric polymorphic types are supported.</li>
45
+ <li>Parametric polymorphic types are not supported.</li>
47
46
  </ul>
48
47
 
49
48
 
@@ -153,7 +152,8 @@ necessary to obtain precise type information.</p>
153
152
  First, the user must indicate which modules are subject to analysis and
154
153
  which modules can be used for the analysis. Next, the user has to indicate
155
154
  where the entry point of the program is. Alternatively, he has to make a
156
- small change to the test cases to use RubyBreaker's testing framework.</p>
155
+ small change to the test cases to use RubyBreaker's testing framework. (If
156
+ you are using RSpec, there is no need for this change.)</p>
157
157
 
158
158
  <h3>Breakable and Broken</h3>
159
159
 
@@ -236,9 +236,7 @@ end
236
236
  <p>In Ruby, as soon as a file is <code>require</code>d, the execution of that file begins.
237
237
  For RubyBreaker, however, it is not trivial to find the actual starting
238
238
  point of the program because there <em>has</em> to be a clear point in time at
239
- which monitoring of <code>Breakable</code> modules begins. <em>This is necessary as
240
- attempting to instrument and monitor at the same time will cause an infinite
241
- loop!</em></p>
239
+ which monitoring of <code>Breakable</code> modules begins.</p>
242
240
 
243
241
  <p>Indicating the program entry point is simply done by inserting the following
244
242
  line at the code (assuming "<code>require 'rubybreaker'</code>" is already placed at
@@ -254,11 +252,11 @@ run the instrumented code (for <code>Breakable</code> modules) which will gather
254
252
  information for methods.</p>
255
253
 
256
254
  <p>Although this seems simple and easy, this is not the recommended way for
257
- analyzing a program. Why? Because RubyBreaker has a built-in testing
258
- framework that (supposedly :)) works seemlessly with the existing tests of
259
- the program.</p>
255
+ analyzing a program. Why? Because RubyBreaker comes with a replacement for
256
+ the built-in testing framework for Ruby. Even better, if you are using
257
+ RSpec, there is no need to change any test code.</p>
260
258
 
261
- <h3>Using RubyBreaker Testing Framework</h3>
259
+ <h3>Using the Built-in Testing Framework</h3>
262
260
 
263
261
  <p>Instead of manually inserting the entry point indicator into the program,
264
262
  the user can take advantage of the Ruby Unit Test framework. This is the
@@ -274,11 +272,28 @@ class TestClassA &lt; Test::Unit::TestCase
274
272
  end
275
273
  </code></pre>
276
274
 
277
- <p>That's it!</p>
275
+ <p>That's it! Also, remember that classes and modules can be re-opened for
276
+ "patches" in Ruby. This means that the original classes or modules do not
277
+ need to be modified to include <code>Broken</code> and/or <code>Breakable</code>. In each test
278
+ suite or test case, those classes and modules can be re-opened to include
279
+ <code>Broken</code> and/or <code>Breakable</code>. The following shows an example of such a test
280
+ case.</p>
278
281
 
279
- <p>Currently, RubyBreaker only supports the standard unit test framework.
280
- Other testing frameworks such as RSpec and Cucumber are not supported at the
281
- moment (but will be in future/hopefully).</p>
282
+ <pre><code>require "rubybreaker"
283
+ require "test/unit"
284
+ class A
285
+ include RubyBreaker::Breakable
286
+ end
287
+ class TestClassA &lt; Test::Unit::TestCase
288
+ ...
289
+ end
290
+ </code></pre>
291
+
292
+ <h3>Using RSpec</h3>
293
+
294
+ <p>If using RSpec, it is even easier! No changes are needed for the test code.
295
+ Really! <em>Well, it is still necessary to <code>require rubybreaker</code> and manually
296
+ insert <code>Breakable</code> and <code>Broken</code> to appropriate classes and modules.</em></p>
282
297
 
283
298
  <h2>Type Annotation</h2>
284
299
 
@@ -316,7 +331,9 @@ instance, <code>fixnum</code> is an object of type <code>Fixnum</code>. Use lowe
316
331
  underscores instead of <em>camelized</em> name. <code>MyClass</code>, for example would be
317
332
  <code>my_class</code> in RubyBreaker type signatures. There is no particular
318
333
  reason for this convention other than it is the common practice used in
319
- RubyDoc.</p>
334
+ RubyDoc. Use <code>/</code> to indicate the namespace delimiter <code>::</code>. For example,
335
+ <code>NamspaceA::ClassB</code> would be represented by <code>namespace_a/class_b</code> in
336
+ a RubyBreaker type signature.</p>
320
337
 
321
338
  <h3>Self Type</h3>
322
339
 
@@ -475,8 +492,6 @@ RubyBreaker. <em>Technical documentation coming soon...</em></p>
475
492
  University of Maryland and represents an object using a structural type with
476
493
  respect to a nominal type.</p>
477
494
 
478
- <hr />
479
-
480
495
  <h1>Copyright</h1>
481
496
 
482
497
  <p>Copyright (c) 2012 Jong-hoon (David) An. All Rights Reserved.</p>