reflexive 0.0.3 → 0.0.4

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 (142) hide show
  1. data/Gemfile +16 -0
  2. data/Rakefile +31 -0
  3. data/config.ru +3 -0
  4. data/reflexive.gemspec +1 -1
  5. data/spec/coderay_html_encoder_spec.rb +57 -0
  6. data/spec/coderay_ruby_scanner_spec.rb +194 -0
  7. data/spec/io_interceptor.rb +64 -0
  8. data/spec/method_lookup_spec.rb +0 -0
  9. data/spec/methods_spec.rb +202 -0
  10. data/spec/rails_integration_spec.rb +139 -0
  11. data/spec/rails_integration_spec_helper.rb +115 -0
  12. data/spec/reflexive_ripper_spec.rb +351 -0
  13. data/spec/reflexive_spec.rb +98 -0
  14. data/spec/ripper_events_recorder.rb +50 -0
  15. data/spec/ripper_spec.rb +758 -0
  16. data/spec/sexp_builder_with_scanner_events.rb +39 -0
  17. data/spec/shell_out.rb +417 -0
  18. data/spec/spec_helper.rb +4 -0
  19. data/spec/test_apps/rails2_test_app/README +243 -0
  20. data/spec/test_apps/rails2_test_app/Rakefile +10 -0
  21. data/spec/test_apps/rails2_test_app/app/controllers/application_controller.rb +10 -0
  22. data/spec/test_apps/rails2_test_app/app/controllers/posts_controller.rb +85 -0
  23. data/spec/test_apps/rails2_test_app/app/helpers/application_helper.rb +3 -0
  24. data/spec/test_apps/rails2_test_app/app/helpers/posts_helper.rb +2 -0
  25. data/spec/test_apps/rails2_test_app/app/models/post.rb +5 -0
  26. data/spec/test_apps/rails2_test_app/app/views/layouts/posts.html.erb +17 -0
  27. data/spec/test_apps/rails2_test_app/app/views/posts/edit.html.erb +12 -0
  28. data/spec/test_apps/rails2_test_app/app/views/posts/index.html.erb +18 -0
  29. data/spec/test_apps/rails2_test_app/app/views/posts/new.html.erb +11 -0
  30. data/spec/test_apps/rails2_test_app/app/views/posts/show.html.erb +3 -0
  31. data/spec/test_apps/rails2_test_app/config/boot.rb +110 -0
  32. data/spec/test_apps/rails2_test_app/config/database.yml +22 -0
  33. data/spec/test_apps/rails2_test_app/config/environment.rb +43 -0
  34. data/spec/test_apps/rails2_test_app/config/environments/development.rb +17 -0
  35. data/spec/test_apps/rails2_test_app/config/environments/production.rb +28 -0
  36. data/spec/test_apps/rails2_test_app/config/environments/test.rb +28 -0
  37. data/spec/test_apps/rails2_test_app/config/initializers/backtrace_silencers.rb +7 -0
  38. data/spec/test_apps/rails2_test_app/config/initializers/inflections.rb +10 -0
  39. data/spec/test_apps/rails2_test_app/config/initializers/mime_types.rb +5 -0
  40. data/spec/test_apps/rails2_test_app/config/initializers/new_rails_defaults.rb +21 -0
  41. data/spec/test_apps/rails2_test_app/config/initializers/session_store.rb +15 -0
  42. data/spec/test_apps/rails2_test_app/config/locales/en.yml +5 -0
  43. data/spec/test_apps/rails2_test_app/config/routes.rb +45 -0
  44. data/spec/test_apps/rails2_test_app/db/development.sqlite3 +0 -0
  45. data/spec/test_apps/rails2_test_app/db/migrate/20100512073155_create_posts.rb +12 -0
  46. data/spec/test_apps/rails2_test_app/db/schema.rb +19 -0
  47. data/spec/test_apps/rails2_test_app/db/seeds.rb +7 -0
  48. data/spec/test_apps/rails2_test_app/doc/README_FOR_APP +2 -0
  49. data/spec/test_apps/rails2_test_app/log/development.log +251 -0
  50. data/spec/test_apps/rails2_test_app/log/production.log +0 -0
  51. data/spec/test_apps/rails2_test_app/log/server.log +0 -0
  52. data/spec/test_apps/rails2_test_app/log/test.log +0 -0
  53. data/spec/test_apps/rails2_test_app/public/404.html +30 -0
  54. data/spec/test_apps/rails2_test_app/public/422.html +30 -0
  55. data/spec/test_apps/rails2_test_app/public/500.html +30 -0
  56. data/spec/test_apps/rails2_test_app/public/favicon.ico +0 -0
  57. data/spec/test_apps/rails2_test_app/public/images/rails.png +0 -0
  58. data/spec/test_apps/rails2_test_app/public/index.html +275 -0
  59. data/spec/test_apps/rails2_test_app/public/javascripts/application.js +2 -0
  60. data/spec/test_apps/rails2_test_app/public/javascripts/controls.js +963 -0
  61. data/spec/test_apps/rails2_test_app/public/javascripts/dragdrop.js +973 -0
  62. data/spec/test_apps/rails2_test_app/public/javascripts/effects.js +1128 -0
  63. data/spec/test_apps/rails2_test_app/public/javascripts/prototype.js +4320 -0
  64. data/spec/test_apps/rails2_test_app/public/robots.txt +5 -0
  65. data/spec/test_apps/rails2_test_app/public/stylesheets/1.css +0 -0
  66. data/spec/test_apps/rails2_test_app/public/stylesheets/scaffold.css +54 -0
  67. data/spec/test_apps/rails2_test_app/script/about +4 -0
  68. data/spec/test_apps/rails2_test_app/script/console +3 -0
  69. data/spec/test_apps/rails2_test_app/script/dbconsole +3 -0
  70. data/spec/test_apps/rails2_test_app/script/destroy +3 -0
  71. data/spec/test_apps/rails2_test_app/script/generate +3 -0
  72. data/spec/test_apps/rails2_test_app/script/performance/benchmarker +3 -0
  73. data/spec/test_apps/rails2_test_app/script/performance/profiler +3 -0
  74. data/spec/test_apps/rails2_test_app/script/plugin +3 -0
  75. data/spec/test_apps/rails2_test_app/script/runner +3 -0
  76. data/spec/test_apps/rails2_test_app/script/server +3 -0
  77. data/spec/test_apps/rails2_test_app/test/fixtures/posts.yml +7 -0
  78. data/spec/test_apps/rails2_test_app/test/functional/posts_controller_test.rb +45 -0
  79. data/spec/test_apps/rails2_test_app/test/performance/browsing_test.rb +9 -0
  80. data/spec/test_apps/rails2_test_app/test/test_helper.rb +38 -0
  81. data/spec/test_apps/rails2_test_app/test/unit/helpers/posts_helper_test.rb +4 -0
  82. data/spec/test_apps/rails2_test_app/test/unit/post_test.rb +8 -0
  83. data/spec/test_apps/rails3_test_app/Gemfile +28 -0
  84. data/spec/test_apps/rails3_test_app/README +244 -0
  85. data/spec/test_apps/rails3_test_app/Rakefile +10 -0
  86. data/spec/test_apps/rails3_test_app/app/controllers/application_controller.rb +4 -0
  87. data/spec/test_apps/rails3_test_app/app/controllers/posts_controller.rb +83 -0
  88. data/spec/test_apps/rails3_test_app/app/helpers/application_helper.rb +2 -0
  89. data/spec/test_apps/rails3_test_app/app/helpers/posts_helper.rb +2 -0
  90. data/spec/test_apps/rails3_test_app/app/models/post.rb +2 -0
  91. data/spec/test_apps/rails3_test_app/app/views/layouts/application.html.erb +14 -0
  92. data/spec/test_apps/rails3_test_app/app/views/posts/_form.html.erb +16 -0
  93. data/spec/test_apps/rails3_test_app/app/views/posts/edit.html.erb +6 -0
  94. data/spec/test_apps/rails3_test_app/app/views/posts/index.html.erb +21 -0
  95. data/spec/test_apps/rails3_test_app/app/views/posts/new.html.erb +5 -0
  96. data/spec/test_apps/rails3_test_app/app/views/posts/show.html.erb +5 -0
  97. data/spec/test_apps/rails3_test_app/config/application.rb +49 -0
  98. data/spec/test_apps/rails3_test_app/config/boot.rb +6 -0
  99. data/spec/test_apps/rails3_test_app/config/database.yml +22 -0
  100. data/spec/test_apps/rails3_test_app/config/environment.rb +5 -0
  101. data/spec/test_apps/rails3_test_app/config/environments/development.rb +19 -0
  102. data/spec/test_apps/rails3_test_app/config/environments/production.rb +42 -0
  103. data/spec/test_apps/rails3_test_app/config/environments/test.rb +32 -0
  104. data/spec/test_apps/rails3_test_app/config/initializers/backtrace_silencers.rb +7 -0
  105. data/spec/test_apps/rails3_test_app/config/initializers/inflections.rb +10 -0
  106. data/spec/test_apps/rails3_test_app/config/initializers/mime_types.rb +5 -0
  107. data/spec/test_apps/rails3_test_app/config/initializers/secret_token.rb +7 -0
  108. data/spec/test_apps/rails3_test_app/config/initializers/session_store.rb +8 -0
  109. data/spec/test_apps/rails3_test_app/config/locales/en.yml +5 -0
  110. data/spec/test_apps/rails3_test_app/config/routes.rb +60 -0
  111. data/spec/test_apps/rails3_test_app/config.ru +4 -0
  112. data/spec/test_apps/rails3_test_app/db/development.sqlite3 +0 -0
  113. data/spec/test_apps/rails3_test_app/db/migrate/20100512075428_create_posts.rb +12 -0
  114. data/spec/test_apps/rails3_test_app/db/schema.rb +19 -0
  115. data/spec/test_apps/rails3_test_app/db/seeds.rb +7 -0
  116. data/spec/test_apps/rails3_test_app/doc/README_FOR_APP +2 -0
  117. data/spec/test_apps/rails3_test_app/log/development.log +349 -0
  118. data/spec/test_apps/rails3_test_app/log/production.log +0 -0
  119. data/spec/test_apps/rails3_test_app/log/server.log +0 -0
  120. data/spec/test_apps/rails3_test_app/log/test.log +0 -0
  121. data/spec/test_apps/rails3_test_app/public/404.html +26 -0
  122. data/spec/test_apps/rails3_test_app/public/422.html +26 -0
  123. data/spec/test_apps/rails3_test_app/public/500.html +26 -0
  124. data/spec/test_apps/rails3_test_app/public/favicon.ico +0 -0
  125. data/spec/test_apps/rails3_test_app/public/images/rails.png +0 -0
  126. data/spec/test_apps/rails3_test_app/public/index.html +279 -0
  127. data/spec/test_apps/rails3_test_app/public/javascripts/application.js +2 -0
  128. data/spec/test_apps/rails3_test_app/public/javascripts/controls.js +965 -0
  129. data/spec/test_apps/rails3_test_app/public/javascripts/dragdrop.js +974 -0
  130. data/spec/test_apps/rails3_test_app/public/javascripts/effects.js +1123 -0
  131. data/spec/test_apps/rails3_test_app/public/javascripts/prototype.js +4874 -0
  132. data/spec/test_apps/rails3_test_app/public/javascripts/rails.js +118 -0
  133. data/spec/test_apps/rails3_test_app/public/robots.txt +5 -0
  134. data/spec/test_apps/rails3_test_app/public/stylesheets/scaffold.css +60 -0
  135. data/spec/test_apps/rails3_test_app/script/rails +9 -0
  136. data/spec/test_apps/rails3_test_app/test/fixtures/posts.yml +11 -0
  137. data/spec/test_apps/rails3_test_app/test/functional/posts_controller_test.rb +49 -0
  138. data/spec/test_apps/rails3_test_app/test/performance/browsing_test.rb +9 -0
  139. data/spec/test_apps/rails3_test_app/test/test_helper.rb +13 -0
  140. data/spec/test_apps/rails3_test_app/test/unit/helpers/posts_helper_test.rb +4 -0
  141. data/spec/test_apps/rails3_test_app/test/unit/post_test.rb +8 -0
  142. metadata +142 -2
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+
3
+ # keeping this in sync with reflexive.gemspec manually
4
+
5
+ gem "rack"
6
+ gem "sinatra"
7
+ gem "sinatra_more"
8
+ gem "coderay"
9
+ gem "rdiscount"
10
+
11
+ group :development do
12
+ gem "rails", "3.0.0.beta3"
13
+ gem "rspec", "2.0.0.beta.8"
14
+ gem "sinatra-reloader"
15
+ gem "thin"
16
+ end
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
2
+
3
+ desc "Run specs (without Rails integration spec - requires rvm, run manually with `spec ./spec/rails_integration_spec.rb')"
4
+ task :spec do
5
+ sh "spec #{ (Dir["./spec/*_spec.rb"] - ["./spec/rails_integration_spec.rb"]).join(" ") }"
6
+ end
7
+
8
+ GEM_NAME = "reflexive"
9
+
10
+ desc "Relese next version of reflexive gem"
11
+ task :release do
12
+ require "rubygems"
13
+ require "rubygems/version"
14
+ require "yaml"
15
+
16
+ current_version = YAML.load(`gem specification #{ GEM_NAME } -r`)["version"] || Gem::Version.new("0.0.0")
17
+ new_version = (current_version.segments[0..-2] + [current_version.segments[-1].succ]).join(".")
18
+ ENV["GEM_VERSION"] = new_version
19
+
20
+ puts "Releasing #{ GEM_NAME } #{ new_version }"
21
+
22
+ sh "gem build #{ GEM_NAME }.gemspec --verbose"
23
+
24
+ sh "gem push #{ GEM_NAME }-#{ new_version }.gem --verbose"
25
+
26
+ sh "gem install #{ GEM_NAME } --version=#{ new_version } --local --verbose"
27
+
28
+ File.delete("#{ GEM_NAME }-#{ new_version }.gem")
29
+ end
30
+
31
+ task :default => :spec
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require File.expand_path("../lib/reflexive/application", __FILE__)
2
+
3
+ run Reflexive::Application
data/reflexive.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.homepage = "http://github.com/dolzenko/reflexive"
7
7
  s.summary = "Reflexive"
8
8
 
9
- s.files = Dir.glob("{lib,public,views}/**/*") + %w(reflexive.gemspec)
9
+ s.files = Dir.glob("{lib,public,views,spec}/**/*") + %w(reflexive.gemspec Rakefile Gemfile config.ru)
10
10
 
11
11
  s.required_ruby_version = '>= 1.9.1'
12
12
 
@@ -0,0 +1,57 @@
1
+ require "reflexive/coderay_html_encoder"
2
+
3
+ describe Reflexive::CodeRayHtmlEncoder do
4
+ def encoder
5
+ Reflexive::CodeRayHtmlEncoder.new(:wrap => :div, :css => :style)
6
+ end
7
+
8
+ it "emits links for :constant tokens" do
9
+ encoder = Reflexive::CodeRayHtmlEncoder.new(:wrap => :div, :css => :style)
10
+ encoder.encode_tokens([["Cons", :constant,
11
+ {:constant_access=>{:name=>"Cons", :scope=>[]}}]]).should(include("<a href"))
12
+ end
13
+
14
+ it "emits links with proper nesting info" do
15
+ tokens = [["Cons", :constant,
16
+ {:constant_access=>{:name=>"Cons", :scope=>["A", "B"]}}]]
17
+
18
+ encoder.encode_tokens(tokens).should include("constant_lookup?name=Cons&scope=A%3A%3AB")
19
+ end
20
+
21
+ it "emits load_path links" do
22
+ tokens = [["f", :content, { :load_path => true }]]
23
+ encoder.encode_tokens(tokens).should include("?path=f")
24
+ end
25
+
26
+ it "emits class method links" do
27
+ tokens = [ [
28
+ "m!", :ident,
29
+ {:method_call=>{:name=>"m!", :receiver=>["A"]} }
30
+ ] ]
31
+ encoder.encode_tokens(tokens).should include("/constants/A/class_methods/m%21")
32
+ end
33
+
34
+ it "emits instance method links" do
35
+ tokens = [ [
36
+ "m!", :ident,
37
+ {:method_call=>{:name=>"m!", :receiver=>["A", :instance]} }
38
+ ] ]
39
+ encoder.encode_tokens(tokens).should include("/constants/A/instance_methods/m%21")
40
+ end
41
+
42
+ it "emits variable assignment id" do
43
+ tokens = [ [
44
+ "a", :ident,
45
+ {:local_variable_assignment=>"1:a"}
46
+ ] ]
47
+ encoder.encode_tokens(tokens).should include("span id='lv:1:a'")
48
+ end
49
+
50
+ it "emits variable access links" do
51
+ tokens = [ [
52
+ "a", :ident,
53
+ {:local_variable_access=>"1:a"}
54
+ ] ]
55
+ encoder.encode_tokens(tokens).should include("href='#lv:1:a'")
56
+ end
57
+ end
@@ -0,0 +1,194 @@
1
+ require "reflexive/coderay_ruby_scanner"
2
+ require "coderay/scanners/ruby"
3
+
4
+ describe Reflexive::CodeRayRubyScanner do
5
+ def reflexive_tokens(src)
6
+ Reflexive::CodeRayRubyScanner.new(src).tokenize
7
+ end
8
+
9
+ def reflexive_tokens_without_meta_and_tags(src)
10
+ Reflexive::CodeRayRubyScanner.new(src).tokenize.
11
+ reject { |t| t[1] == :meta_scope }.
12
+ reject { |t| t[0] == :method_call }.
13
+ map { |t| t[2].is_a?(Hash) ? t[0..1] : t }
14
+ end
15
+
16
+ def coderay_tokens(src)
17
+ squeezed_tokes = []
18
+ ::CodeRay::Scanners::Ruby.new(src).tokenize.each do |token|
19
+ if squeezed_tokes.size > 0 &&
20
+ squeezed_tokes[-1][1] == token[1]
21
+ squeezed_tokes[-1][0] << token[0]
22
+ else
23
+ squeezed_tokes << token
24
+ end
25
+ end
26
+ end
27
+
28
+ pending "squeezes constants" do
29
+ src = <<-RUBY
30
+ class ConstRef < Const::PathRef
31
+ RefenceConstInClassBody = ::TopConstRef
32
+ def m
33
+ Const::PathRef
34
+ end
35
+ end
36
+
37
+ class Const::PathRef < ::TopConstRef
38
+ def self.m
39
+ reference_in_method_body ::TopConstRef
40
+ end
41
+ end
42
+
43
+ class ::TopConstRef
44
+ end
45
+
46
+ class Const::Deeply::Nested::PathRef < ConstRef
47
+ end
48
+ RUBY
49
+ tokens = reflexive_tokens(src)
50
+ tokens.should include(["ConstRef", :constant, { :scope => nil }])
51
+ tokens.should include(["Const::PathRef", :constant, { :scope => ["ConstRef"] }])
52
+ tokens.should include(["Const::PathRef", :constant, { :scope => nil }])
53
+ tokens.should include(["::TopConstRef", :constant, { :scope => nil }])
54
+ tokens.should include(["::TopConstRef", :constant, { :scope => ["Const::PathRef"] }])
55
+ tokens.should include(["Const::Deeply::Nested::PathRef", :constant, { :scope => nil }])
56
+ end
57
+
58
+ it "injects load_path tags" do
59
+ reflexive_tokens("require('f')").should include(["f", :content, { :load_path => true }])
60
+ reflexive_tokens("require 'f'").should include(["f", :content, { :load_path => true }])
61
+ end
62
+
63
+ it "injects instance method tags"
64
+
65
+ ONE_LINERS = <<-RUBY.gsub(/^ */, "")
66
+ %Q{str}
67
+ %r<regexp>
68
+ :symbol
69
+ :@instance_var_symbol
70
+ :@@class_var_symbol
71
+ :$global_var_symbol
72
+ :ConstantSymbol
73
+ :+
74
+ :if
75
+ #!/usr/bin/env ruby
76
+ %q[haha! [nesting [rocks] ] ! ]
77
+ %Q[hehe! \#{ %Q]nesting \#{"really"} rocks] } ! ]
78
+ some_string.to_i /\\s+/
79
+ S = 'bla' * 100 + "\n" + "\t"*4
80
+ :"\#{undef :blubb}\#@@cv"
81
+ undef :"bla", /, :"\#{undef :blubb}\#@@cv"
82
+ @hash.delete_if { |o,| yield(o) }
83
+ "double quoted string"
84
+ # comment
85
+ "a \#{ b + "c"}"
86
+ 42 if true
87
+ /regexp with modifiers/xm
88
+ a = ?s
89
+ q = "\\n"
90
+ call_something()
91
+ a = 1 && 2 || 3
92
+ @ivar = 123
93
+ @@cvar = 345
94
+ $gvar = 345
95
+ float = 1.2345
96
+ `shell`
97
+ v = %w(w1 w2)
98
+ "a\#{" b \#{@c} d" if @c} d \#{@e}; f."
99
+ RUBY
100
+
101
+ # ONE_LINERS.split("\n").each do |src|
102
+ # it "should parse `#{ src }' just as CodeRay parser does" do
103
+ # reflexive_tokens(src).should == coderay_tokens(src)
104
+ # end
105
+ # end
106
+
107
+
108
+ it "generates CodeRay compatible token stream" do
109
+ src = <<-RUBY.gsub(/^ */, "")
110
+ #{ ONE_LINERS }
111
+ [].each do |*args, &block|
112
+ self.class.define_method do
113
+ end
114
+ end
115
+ class Qwe < Asd
116
+ alias qwe asd
117
+ module Sdf
118
+ def self.sm
119
+ end
120
+ end
121
+ end
122
+ =begin
123
+ heredoc1
124
+ =end
125
+ <<-QWE
126
+ QWE
127
+ if 1 > 0
128
+ elsif false
129
+ end
130
+ begin
131
+ 42
132
+ rescue Exception => e
133
+ [] << 'q'
134
+ end
135
+ def `(cmd)
136
+ end
137
+ RUBY
138
+ expected_tokens = [
139
+ [:open, :string], ["%Q{", :delimiter], ["str", :content], ["}", :delimiter], [:close, :string], ["\n", :space],
140
+ [:open, :regexp], ["%r<", :delimiter], ["regexp", :content], [">", :delimiter], [:close, :regexp], ["\n", :space],
141
+ [:open, :symbol], [":", :delimiter], ["symbol", :content], [:close, :symbol], ["\n", :space],
142
+ [:open, :symbol], [":", :delimiter], ["@instance_var_symbol", :content], [:close, :symbol], ["\n", :space],
143
+ [:open, :symbol], [":", :delimiter], ["@@class_var_symbol", :content], [:close, :symbol], ["\n", :space],
144
+ [:open, :symbol], [":", :delimiter], ["$global_var_symbol", :content], [:close, :symbol], ["\n", :space],
145
+ [:open, :symbol], [":", :delimiter], ["ConstantSymbol", :content], [:close, :symbol], ["\n", :space],
146
+ [:open, :symbol], [":", :delimiter], ["+", :content], [:close, :symbol], ["\n", :space],
147
+ [:open, :symbol], [":", :delimiter], ["if", :content], [:close, :symbol], ["\n", :space],
148
+ ["#!/usr/bin/env ruby\n", :comment], [:open, :string], ["%q[", :delimiter], ["haha! [nesting [rocks] ] ! ", :content], ["]", :delimiter], [:close, :string], ["\n", :space],
149
+ [:open, :string], ["%Q[", :delimiter], ["hehe! ", :content], [:open, :inline], ["\#{", :inline_delimiter], [" ", :space], [:open, :string], ["%Q]", :delimiter], ["nesting ", :content], [:open, :inline], ["\#{", :inline_delimiter], [:open, :string], ["\"", :delimiter], ["really", :content], ["\"", :delimiter], [:close, :string], ["}", :inline_delimiter], [:close, :inline], [" rocks", :content], ["]", :delimiter], [:close, :string], [" ", :space], ["}", :inline_delimiter], [:close, :inline], [" ! ", :content], ["]", :delimiter], [:close, :string], ["\n", :space],
150
+ ["some_string", :ident], [".", :operator], ["to_i", :ident], [" ", :space], [:open, :regexp], ["/", :delimiter], ["\\s+", :content], ["/", :delimiter], [:close, :regexp], ["\n", :space],
151
+ ["S", :constant], [" ", :space], ["=", :operator], [" ", :space], [:open, :string], ["'", :delimiter], ["bla", :content], ["'", :delimiter], [:close, :string], [" ", :space], ["*", :operator], [" ", :space], ["100", :integer], [" ", :space], ["+", :operator], [" ", :space], [:open, :string], ["\"", :delimiter], ["\n", :content], ["\"", :delimiter], [:close, :string], [" ", :space], ["+", :operator], [" ", :space], [:open, :string], ["\"", :delimiter], ["\t", :content], ["\"", :delimiter], [:close, :string], ["*", :operator], ["4", :integer], ["\n", :space],
152
+ [:open, :symbol], [":\"", :delimiter], [:open, :inline], ["\#{", :inline_delimiter], ["undef", :content], [:close, :symbol], [" ", :space], [:open, :symbol], [":", :delimiter], ["blubb", :content], [:close, :symbol], ["}", :inline_delimiter], [:close, :inline], ["#", :escape], ["@@cv", :class_variable], ["\"", :delimiter], [:close, :string], ["\n", :space],
153
+ ["undef", :reserved], [" ", :space], [:open, :symbol], [":\"", :delimiter], ["bla", :content], ["\"", :delimiter], [:close, :symbol], [",", :operator], [" ", :space], ["/,", :operator], [" ", :space], [:open, :symbol], [":\"", :delimiter], [:open, :inline], ["\#{", :inline_delimiter], ["undef", :content], [:close, :symbol], [" ", :space], [:open, :symbol], [":", :delimiter], ["blubb", :content], [:close, :symbol], ["}", :inline_delimiter], [:close, :inline], ["#", :escape], ["@@cv", :class_variable], ["\"", :delimiter], [:close, :string], ["\n", :space],
154
+ ["@hash", :instance_variable], [".", :operator], ["delete_if", :ident], [" ", :space], ["{", :operator], [" ", :space], ["|", :operator], ["o", :ident], [",|", :operator], [" ", :space], ["yield", :reserved], ["(", :operator], ["o", :ident], [")", :operator], [" ", :space], ["}", :operator], ["\n", :space],
155
+ [:open, :string], ["\"", :delimiter], ["double quoted string", :content], ["\"", :delimiter], [:close, :string], ["\n", :space],
156
+ ["# comment\n", :comment], [:open, :string], ["\"", :delimiter], ["a ", :content], [:open, :inline], ["\#{", :inline_delimiter], [" ", :space], ["b", :ident], [" ", :space], ["+", :operator], [" ", :space], [:open, :string], ["\"", :delimiter], ["c", :content], ["\"", :delimiter], [:close, :string], ["}", :inline_delimiter], [:close, :inline], ["\"", :delimiter], [:close, :string], ["\n", :space],
157
+ ["42", :integer], [" ", :space], ["if", :reserved], [" ", :space], ["true", :reserved], ["\n", :space],
158
+ [:open, :regexp], ["/", :delimiter], ["regexp with modifiers", :content], ["/xm", :delimiter], [:close, :regexp], ["\n", :space],
159
+ ["a", :ident], [" ", :space], ["=", :operator], [" ", :space], ["?s", :integer], ["\n", :space],
160
+ ["q", :ident], [" ", :space], ["=", :operator], [" ", :space], [:open, :string], ["\"", :delimiter], ["\\n", :content], ["\"", :delimiter], [:close, :string], ["\n", :space],
161
+ ["call_something", :ident], ["()", :operator], ["\n", :space],
162
+ ["a", :ident], [" ", :space], ["=", :operator], [" ", :space], ["1", :integer], [" ", :space], ["&&", :operator], [" ", :space], ["2", :integer], [" ", :space], ["||", :operator], [" ", :space], ["3", :integer], ["\n", :space],
163
+ ["@ivar", :instance_variable], [" ", :space], ["=", :operator], [" ", :space], ["123", :integer], ["\n", :space],
164
+ ["@@cvar", :class_variable], [" ", :space], ["=", :operator], [" ", :space], ["345", :integer], ["\n", :space],
165
+ ["$gvar", :global_variable], [" ", :space], ["=", :operator], [" ", :space], ["345", :integer], ["\n", :space],
166
+ ["float", :ident], [" ", :space], ["=", :operator], [" ", :space], ["1.2345", :float], ["\n", :space],
167
+ [:open, :shell], ["`", :delimiter], ["shell", :content], ["`", :delimiter], [:close, :shell], ["\n", :space],
168
+ ["v", :ident], [" ", :space], ["=", :operator], [" ", :space], ["%w(w1 w2)", :content], ["\n", :space],
169
+ [:open, :string], ["\"", :delimiter], ["a", :content], [:open, :inline], ["\#{", :inline_delimiter], [:open, :string], ["\"", :delimiter], [" b ", :content], [:open, :inline], ["\#{", :inline_delimiter], ["@c", :instance_variable], ["}", :inline_delimiter], [:close, :inline], [" d", :content], ["\"", :delimiter], [:close, :string], [" ", :space], ["if", :reserved], [" ", :space], ["@c", :instance_variable], ["}", :inline_delimiter], [:close, :inline], [" d ", :content], [:open, :inline], ["\#{", :inline_delimiter], ["@e", :instance_variable], ["}", :inline_delimiter], [:close, :inline], ["; f.", :content], ["\"", :delimiter], [:close, :string], ["\n\n", :space], ["[].", :operator], ["each", :ident], [" ", :space], ["do", :reserved], [" ", :space], ["|*", :operator], ["args", :ident], [",", :operator], [" ", :space], ["&", :operator], ["block", :ident], ["|", :operator], ["\n", :space],
170
+ ["self", :reserved], [".", :operator], ["class", :ident], [".", :operator], ["define_method", :ident], [" ", :space], ["do", :reserved], ["\n", :space],
171
+ ["end", :reserved], ["\n", :space],
172
+ ["end", :reserved], ["\n", :space],
173
+ ["class", :reserved], [" ", :space], ["Qwe", :constant], [" ", :space], ["<", :operator], [" ", :space], ["Asd", :constant], ["\n", :space],
174
+ ["alias", :reserved], [" ", :space], ["qwe", :ident], [" ", :space], ["asd", :ident], ["\n", :space],
175
+ ["module", :reserved], [" ", :space], ["Sdf", :constant], ["\n", :space],
176
+ ["def", :reserved], [" ", :space], ["self", :reserved], [".", :operator], ["sm", :ident], ["\n", :space],
177
+ ["end", :reserved], ["\n", :space],
178
+ ["end", :reserved], ["\n", :space],
179
+ ["end", :reserved], ["\n", :space],
180
+ ["=begin\nheredoc1\n=end\n", :comment], ["<<-QWE", :heredoc_beg], ["\n", :space],
181
+ ["if", :reserved], [" ", :space], ["1", :integer], [" ", :space], [">", :operator], [" ", :space], ["0", :integer], ["\n", :space],
182
+ ["elsif", :reserved], [" ", :space], ["false", :reserved], ["\n", :space],
183
+ ["end", :reserved], ["\n", :space],
184
+ ["begin", :reserved], ["\n", :space],
185
+ ["42", :integer], ["\n", :space],
186
+ ["rescue", :reserved], [" ", :space], ["Exception", :constant], [" ", :space], ["=>", :operator], [" ", :space], ["e", :ident], ["\n", :space],
187
+ ["[]", :operator], [" ", :space], ["<<", :operator], [" ", :space], [:open, :string], ["'", :delimiter], ["q", :content], ["'", :delimiter], [:close, :string], ["\n", :space],
188
+ ["end", :reserved], ["\n", :space],
189
+ ["def", :reserved], [" ", :space], ["`", :method], ["(", :operator], ["cmd", :ident], [")", :operator], ["\n", :space],
190
+ ["end", :reserved], ["\n", :space]]
191
+ reflexive_tokens_without_meta_and_tags(src).should == expected_tokens
192
+ end
193
+ end
194
+
@@ -0,0 +1,64 @@
1
+ # Safe way to intercept IO stream
2
+ # where just replacing STDOUT doesn't work:
3
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=5217&group_id=426&atid=1698
4
+ #
5
+ module IoInterceptor
6
+ def intercept
7
+ begin
8
+ @intercept = true
9
+ @intercepted = ""
10
+ yield
11
+ ensure
12
+ @intercept = false
13
+ end
14
+ @intercepted
15
+ end
16
+
17
+ def supress
18
+ begin
19
+ @supress = true
20
+ yield
21
+ ensure
22
+ @supress = false
23
+ end
24
+ end
25
+
26
+ def write(str)
27
+ if @supress || @intercept
28
+ @intercepted << str.to_s unless @supress
29
+ str.size
30
+ else
31
+ super
32
+ end
33
+ end
34
+ end
35
+
36
+ if $PROGRAM_NAME == __FILE__
37
+ require 'spec'
38
+
39
+ describe IoInterceptor do
40
+ before do
41
+ STDOUT.extend(IoInterceptor)
42
+ end
43
+
44
+ it "intercepts output to stream when the stream is extended with it" do
45
+ STDOUT.intercept { STDOUT.puts("42") }.should == "42\n"
46
+ STDOUT.intercept { STDOUT.puts("24") }.should == "24\n"
47
+ end
48
+
49
+ it "intercepted IO#write still returns the number of bytes written" do
50
+ STDOUT.intercept { STDOUT.write("42").should == 2 }
51
+ end
52
+
53
+ it "intercepted IO#write argument is converted using to_s" do
54
+ obj = "42"
55
+ def obj.to_s
56
+ "custom to_s"
57
+ end
58
+
59
+ STDOUT.intercept { STDOUT.puts(obj) }.should == "#{ obj.to_s }\n"
60
+ end
61
+ end
62
+
63
+ exit ::Spec::Runner::CommandLine.run
64
+ end
File without changes
@@ -0,0 +1,202 @@
1
+ require "reflexive/methods"
2
+
3
+ Rspec::Matchers.define :generate_methods do |expected|
4
+ match do |actual|
5
+ Reflexive::Methods.new(actual).all == eval(expected)
6
+ end
7
+
8
+ failure_message_for_should do |actual|
9
+ require "pp"
10
+ require "stringio"
11
+ pp_out = StringIO.new
12
+ PP.pp(Reflexive::Methods.new(actual).all, pp_out)
13
+ "expected:\n#{ expected }\ngot:\n#{ pp_out.string }"
14
+ end
15
+ end
16
+
17
+ describe Reflexive::Methods do
18
+ describe "ModuleInclusionC" do
19
+ module ModuleInclusionA
20
+ def module_instance_from_A_WTF!
21
+ end
22
+ end
23
+
24
+ module ModuleInclusionB
25
+ include ModuleInclusionA
26
+
27
+ def module_instance_from_B_WTF!
28
+ end
29
+ end
30
+
31
+ module ModuleInclusionC
32
+ include ModuleInclusionB
33
+ end
34
+
35
+ it "works" do
36
+ ModuleInclusionC.should generate_methods(<<-METHODS_PP)
37
+ [{"[M] ModuleInclusionB"=>
38
+ {:instance=>{:public=>[:module_instance_from_B_WTF!]}}},
39
+ {"[M] ModuleInclusionA"=>
40
+ {:instance=>{:public=>[:module_instance_from_A_WTF!]}}}]
41
+ METHODS_PP
42
+ end
43
+ end
44
+ describe "Inheritance" do
45
+ class InheritanceA
46
+ def self.singleton_inherited_from_A_WTF!
47
+ end
48
+ end
49
+
50
+ class InheritanceB < InheritanceA
51
+ end
52
+
53
+ class InheritanceC < InheritanceB
54
+ def test
55
+ end
56
+ end
57
+
58
+ it "works" do
59
+ InheritanceC.should generate_methods(<<-METHODS_PP)
60
+ [{"[C] InheritanceC"=>{:instance=>{:public=>[:test]}}},
61
+ {"[C] InheritanceA"=>{:class=>{:public=>[:singleton_inherited_from_A_WTF!]}}}]
62
+ METHODS_PP
63
+ end
64
+ end
65
+
66
+ describe "SingletonAndInstance" do
67
+ module M
68
+ def instance_from_moduleWTF!
69
+ end
70
+ end
71
+
72
+ module SM
73
+ def singleton_from_moduleWTF!
74
+ end
75
+ end
76
+
77
+ class SingletonAndInstanceTest
78
+ include M
79
+ extend SM
80
+
81
+ def self.singletonWTF!
82
+ end
83
+
84
+ def instanceWTF!
85
+ end
86
+ end
87
+
88
+ it "works" do
89
+ SingletonAndInstanceTest.should generate_methods(<<-METHODS_PP)
90
+ [{"[C] SingletonAndInstanceTest"=>
91
+ {:class=>{:public=>[:singletonWTF!]},
92
+ :instance=>{:public=>[:instanceWTF!]}}},
93
+ {"S[M] SM"=>{:class=>{:public=>[:singleton_from_moduleWTF!]}}},
94
+ {"[M] M"=>{:instance=>{:public=>[:instance_from_moduleWTF!]}}}]
95
+ METHODS_PP
96
+ end
97
+ end
98
+
99
+ describe "ExtendWithInstanceAndClass" do
100
+ module ExtendWithInstanceAndClassM
101
+ def self.singleton_WTF!
102
+ end
103
+
104
+ def instance_WTF!
105
+ end
106
+ end
107
+
108
+ class ExtendWithInstanceAndClass
109
+ extend ExtendWithInstanceAndClassM
110
+ end
111
+
112
+ it "works" do
113
+ ExtendWithInstanceAndClass.should generate_methods(<<-METHODS_PP)
114
+ [{"S[M] ExtendWithInstanceAndClassM"=>{:class=>{:public=>[:instance_WTF!]}}}]
115
+ METHODS_PP
116
+ end
117
+ end
118
+
119
+ describe "SingletonVisibility" do
120
+ class SingletonVisibility
121
+ def self.class_method
122
+ end
123
+
124
+ class << self
125
+
126
+ def public_singleton_method
127
+ end
128
+ public :public_singleton_method
129
+
130
+ def protected_singleton_method
131
+ end
132
+ protected :protected_singleton_method
133
+
134
+ def private_singleton_method
135
+ end
136
+ private :private_singleton_method
137
+ end
138
+ end
139
+
140
+ it "works" do
141
+ SingletonVisibility.should generate_methods(<<-METHODS_PP)
142
+ [{"[C] SingletonVisibility"=>
143
+ {:class=>
144
+ {:public=>[:class_method, :public_singleton_method],
145
+ :protected=>[:protected_singleton_method],
146
+ :private=>[:private_singleton_method]}}}]
147
+ METHODS_PP
148
+ end
149
+ end
150
+
151
+ describe "SingletonOverrides" do
152
+ class SingletonOverridesA
153
+ def self.overriden
154
+ puts "A"
155
+ # super
156
+ end
157
+ end
158
+
159
+ module SingletonOverridesMB
160
+ def overriden
161
+ puts " MB"
162
+ super
163
+ end
164
+ end
165
+
166
+ class SingletonOverridesB < SingletonOverridesA
167
+ extend SingletonOverridesMB
168
+
169
+ def self.overriden
170
+ end
171
+ end
172
+
173
+ module SingletonOverridesMC
174
+ def overriden
175
+ end
176
+
177
+ def singleton_WTF
178
+ end
179
+ end
180
+
181
+ class SingletonOverridesC < SingletonOverridesB
182
+ extend SingletonOverridesMC
183
+
184
+ def self.class_WTF
185
+ end
186
+
187
+ def self.overriden
188
+ end
189
+ end
190
+
191
+ it "works" do
192
+ SingletonOverridesC.should generate_methods(<<-METHODS_PP)
193
+ [{"[C] SingletonOverridesC"=>{:class=>{:public=>[:class_WTF, :overriden]}}},
194
+ {"S[M] SingletonOverridesMC"=>
195
+ {:class=>{:public=>[:overriden, :singleton_WTF]}}},
196
+ {"[C] SingletonOverridesB"=>{:class=>{:public=>[:overriden]}}},
197
+ {"S[M] SingletonOverridesMB"=>{:class=>{:public=>[:overriden]}}},
198
+ {"[C] SingletonOverridesA"=>{:class=>{:public=>[:overriden]}}}]
199
+ METHODS_PP
200
+ end
201
+ end
202
+ end