reflexive 0.0.6 → 0.1.0

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.
@@ -10,6 +10,10 @@ shared_examples_for "fresh Rails app with Reflexive installed" do
10
10
  get("/").should include("Welcome aboard")
11
11
  end
12
12
 
13
+ it "doesn't respond on not existing path" do
14
+ proc { get("/not_exist") }.should raise_error
15
+ end
16
+
13
17
  it "responds for Reflexive paths" do
14
18
  constant_reflexion = get("/reflexive/constants/ActiveRecord::Base")
15
19
  constant_reflexion.should include("ActiveRecord")
@@ -112,11 +116,14 @@ describe "Integration with" do
112
116
  class Application < Rails::Application
113
117
  config.middleware.insert_after("Rack::Lock", "Reflexive::Application")
114
118
  RUBY
119
+
120
+ patch_app_file("Gemfile", /\z/, "\ngem 'reflexive'")
115
121
  end
116
122
 
117
123
  it "properly" do
118
124
  Dir.chdir($app_dir) do
119
125
  IO.read("config/application.rb").should include("Reflexive")
126
+ IO.read("Gemfile").should include("reflexive")
120
127
  end
121
128
  end
122
129
 
@@ -69,25 +69,35 @@ def build_and_install_test_gem
69
69
  end
70
70
  end
71
71
 
72
+ SERVER_STARTUP_TIME = 20
72
73
  def spawn_server_and_wait_for_response(cmd)
73
74
  $server_pid = spawn(tmp_gemset_env, cmd)
74
- puts "Spawned server with #{ $server_pid } PID"
75
- tries = 0
76
- print "Waiting for server to start..."
77
- started = false
78
- while (tries += 1) < 10 && !started
79
- started = get("/").include?("Welcome aboard") rescue false
80
- print "."
81
- sleep 1
75
+ begin
76
+ trap("CLD") { raise "Failed to start server: server died prematurely" }
77
+ puts "Spawned server with #{ $server_pid } PID"
78
+ tries = 0
79
+ print "Waiting for server to start..."
80
+ started = false
81
+ while (tries += 1) < SERVER_STARTUP_TIME && !started
82
+ started = get("/").include?("Welcome aboard") rescue false
83
+ print "."
84
+ sleep 1
85
+ end
86
+ print "\n"
87
+ unless started
88
+ raise "Failed to start server: server didn't respond in #{ SERVER_STARTUP_TIME } seconds"
89
+ end
90
+ rescue Exception => e
91
+ raise e.exception("Failed to start server: #{ e.message }")
92
+ ensure
93
+ trap("CLD", nil)
82
94
  end
83
- print "\n"
84
- abort "Failed to start server" unless started
85
95
  end
86
96
 
87
97
  def terminate_server_blocking
88
98
  puts "Terminating server with #{ $server_pid } PID..."
89
99
  `kill -9 #{ $server_pid }`
90
- Process::waitpid2($server_pid)
100
+ Process::waitpid2($server_pid) rescue nil
91
101
  end
92
102
 
93
103
  def get(path)
@@ -57,7 +57,7 @@ describe Reflexive::ReflexiveRipper do
57
57
  describe "injects method call scanner event tags" do
58
58
  specify "m!" do
59
59
  scanner_events_for("m!").should(have_tags(
60
- {:method_call=>{:name=>"m!", :receiver=>[], :scope => []}}
60
+ {:method_call=>{:name=>"m!", :receiver=>:class, :scope => []}}
61
61
  ))
62
62
  end
63
63
 
@@ -109,7 +109,7 @@ describe Reflexive::ReflexiveRipper do
109
109
  specify "1.tap { (dv = 1).tap { puts dv } }" do
110
110
  scanner_events_for("1.tap { (dv = 1).tap { puts dv } }").should(have_exact_tags(
111
111
  {:local_variable_assignment=>"2:dv"},
112
- {:method_call=>{:name=>"puts", :receiver=>[], :scope => []}},
112
+ {:method_call=>{:name=>"puts", :receiver=>:class, :scope => []}},
113
113
  {:local_variable_access=>"2:dv"}
114
114
  ))
115
115
  end
@@ -123,8 +123,9 @@ describe Reflexive::ReflexiveRipper do
123
123
  specify "tv = 1; def m; puts tv; end" do
124
124
  scanner_events_for("tv = 1; def m; puts tv; end").should(have_tags(
125
125
  {:local_variable_assignment=>"1:tv"},
126
- {:method_call=>{:name=>"puts", :receiver=>[:instance], :scope => []}},
127
- {:method_call=>{:name=>"tv", :receiver=>[:instance], :scope => []}}))
126
+ {:method_call=>{:name=>"puts", :receiver=>:instance, :scope => []}},
127
+ {:method_call=>{:name=>"tv", :receiver=>:instance, :scope => []}}
128
+ ))
128
129
  end
129
130
 
130
131
  end
@@ -133,44 +134,54 @@ describe Reflexive::ReflexiveRipper do
133
134
  describe "for method calls" do
134
135
  specify "from top level" do
135
136
  scanner_events_for("m()").should(have_tags(
136
- {:method_call=>{:name=>"m", :receiver=>[], :scope => []}}))
137
+ {:method_call=>{:name=>"m", :receiver=>:class, :scope => []}}
138
+ ))
137
139
  end
138
140
 
139
141
  specify "class definition level" do
140
142
  scanner_events_for("class C; cm(); end").should(have_tags(
141
- {:method_call=>{:name=>"cm", :receiver=>["C"], :scope => ["C"]}}))
143
+ {:method_call=>{:name=>"cm", :receiver=>:class, :scope => ["C"]}}
144
+ ))
142
145
  scanner_events_for("module M; cm(); end").should(have_tags(
143
- {:method_call=>{:name=>"cm", :receiver=>["M"], :scope => ["M"]}}))
146
+ {:method_call=>{:name=>"cm", :receiver=>:class, :scope => ["M"]}}
147
+ ))
144
148
  end
145
149
 
146
150
  specify "class instance level" do
147
151
  scanner_events_for("class C; def im1; im2; end end").should(have_tags(
148
- {:method_call=>{:name=>"im2", :receiver=>["C", :instance], :scope => ["C"]}}))
152
+ {:method_call=>{:name=>"im2", :receiver=>:instance, :scope => ["C"]}}
153
+ ))
149
154
  scanner_events_for("module M; def im1; im2; end end").should(have_tags(
150
- {:method_call=>{:name=>"im2", :receiver=>["M", :instance], :scope => ["M"]}}))
155
+ {:method_call=>{:name=>"im2", :receiver=>:instance, :scope => ["M"]}}
156
+ ))
151
157
  end
152
158
 
153
159
  specify "class singleton level" do
154
160
  scanner_events_for("class C; def self.cm1() cm2; end end").should(have_tags(
155
- {:method_call=>{:name=>"cm2", :receiver=>["C"], :scope => ["C"]}}))
161
+ {:method_call=>{:name=>"cm2", :receiver=>:class, :scope => ["C"]}}
162
+ ))
156
163
  scanner_events_for("module M; def self.cm1() cm2; end end").should(have_tags(
157
- {:method_call=>{:name=>"cm2", :receiver=>["M"], :scope => ["M"]}}))
164
+ {:method_call=>{:name=>"cm2", :receiver=>:class, :scope => ["M"]}}
165
+ ))
166
+ end
167
+
168
+ specify "class singleton level for methods defined with class << self" do
169
+ scanner_events_for("class C; class << self; def cm1(); cm2; end end end").should(have_tags(
170
+ {:method_call=>{:name=>"cm2", :receiver=>:class, :scope => ["C"]}}
171
+ ))
158
172
  end
159
173
 
160
- pending "nested method calls with constant references" do
174
+ specify "nested method calls with constant references" do
161
175
  src = <<-RUBY
162
176
  module M
163
177
  class C
164
- def self.m
165
- end
166
- end
167
- end
168
- class M::C
169
- def m
170
- c = C.m
171
178
  end
179
+ C.new
172
180
  end
173
181
  RUBY
182
+ scanner_events_for(src).should(have_tags(
183
+ {:method_call=>{:name=>"new", :receiver=>["C"], :scope => ["M"]}}
184
+ ))
174
185
  end
175
186
  end
176
187
 
@@ -233,6 +244,33 @@ describe Reflexive::ReflexiveRipper do
233
244
  ))
234
245
 
235
246
  end
247
+
248
+ specify "from instance methods params" do
249
+ scanner_events_for("def m(a = C.new(m1), b = D.new(m2)); end").should(have_tags(
250
+ {:constant_access=>{:name=>"C", :scope=>[]}},
251
+ {:constant_access=>{:name=>"D", :scope=>[]}}
252
+ ))
253
+ end
254
+
255
+ specify "for superclass" do
256
+ scanner_events_for("class C < D; end").should(have_tags(
257
+ {:constant_access=>{:name=>"D", :scope=>[]}}
258
+ ))
259
+ end
260
+
261
+ specify "autoload hint" do
262
+ scanner_events_for("module M; autoload :C; end").should(have_tags(
263
+ {:constant_access=>{:name=>"C", :scope=>["M"]}}
264
+ ))
265
+
266
+ scanner_events_for("module M; autoload 'C'; end").should(have_tags(
267
+ {:constant_access=>{:name=>"C", :scope=>["M"]}}
268
+ ))
269
+
270
+ scanner_events_for("module M; autoload('C'); end").should(have_tags(
271
+ {:constant_access=>{:name=>"C", :scope=>["M"]}}
272
+ ))
273
+ end
236
274
  end
237
275
  end
238
276
 
@@ -26,6 +26,13 @@ end
26
26
 
27
27
  C2.extend(M2)
28
28
 
29
+ module ModuleDescendantBaseModule
30
+ end
31
+
32
+ module ModuleDescendantModule
33
+ include ModuleDescendantBaseModule
34
+ end
35
+
29
36
  describe "Reflexive.loaded_features_lookup" do
30
37
  before(:all) do
31
38
  @native_feature = $LOADED_FEATURES.detect { |f| f =~ /\.so\z/ }
@@ -61,6 +68,10 @@ describe "Reflexive.constant_lookup" do
61
68
  Reflexive.constant_lookup("::String", "Some::Ignored::Scope").should == ::String
62
69
  end
63
70
 
71
+ it "looks up top-level constants when passed empty scope" do
72
+ Reflexive.constant_lookup("String", "").should == ::String
73
+ end
74
+
64
75
  it "returns nil for non existing top-level constant" do
65
76
  Reflexive.constant_lookup("::StringAsd", "Some::Ignored::Scope").should == nil
66
77
  end
@@ -96,4 +107,8 @@ describe "Reflexive.descendants" do
96
107
  it "finds singleton class descendant" do
97
108
  Reflexive.descendants(M2).should =~ [C2]
98
109
  end
110
+
111
+ it "reports modules which include module as descendants" do
112
+ Reflexive.descendants(ModuleDescendantBaseModule) =~ [ModuleDescendantModule]
113
+ end
99
114
  end
@@ -19,9 +19,26 @@
19
19
  <% unless @methods.files.empty? %>
20
20
  <div>
21
21
  <h4>Defined In Files</h4>
22
- <% @methods.files.sort.each do |path| %>
22
+
23
+ <% files = @methods.files.sort %>
24
+ <% shown, hidden = files[0..5], files[6..-1] %>
25
+
26
+ <% shown.each do |path| %>
23
27
  <%= link_to_file(path) %><br/>
24
28
  <% end %>
29
+
30
+ <% if hidden && !hidden.empty? %>
31
+ <div class="opener">
32
+ <a class="trigger" href="#">
33
+ ... <%= hidden.size %> files more
34
+ </a>
35
+ <div class="content">
36
+ <% hidden.each do |path| %>
37
+ <%= link_to_file(path) %><br/>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+ <% end %>
25
42
  </div>
26
43
  <% end %>
27
44
 
data/views/dashboard.erb CHANGED
@@ -1,10 +1,9 @@
1
- <h1>
2
- Reflexive </h1>
1
+ <h1> Reflexive </h1>
3
2
 
4
3
  <div class="dashboard">
5
4
  <% if defined?(ActiveRecord::Base) || defined?(ApplicationController) %>
6
5
  <div class="row">
7
- <div class="column">
6
+ <div class="column first">
8
7
  <% if defined?(::ActiveRecord::Base) %>
9
8
  <h2>Models</h2>
10
9
 
@@ -27,7 +26,7 @@
27
26
  </div>
28
27
  <% end %>
29
28
  <div class="row">
30
- <div class="column">
29
+ <div class="column first">
31
30
  <h2>Favorites</h2>
32
31
  <% favorites = filter_existing_constants(%w(Rails ActiveSupport ActiveResource
33
32
  ActiveRecord ActionView ActionController ActionDispatch ActionMailer ActiveModel
data/views/layout.erb CHANGED
@@ -10,6 +10,16 @@
10
10
  </head>
11
11
  <body>
12
12
 
13
+ <% if Reflexive.class_reloading_active? %>
14
+ <div style="background-color: #ffc0cb; border: 1px solid gray; padding: 1em 1em; width: 500px">
15
+ Warning! You're running Reflexive with <code>config.cache_classes = false</code> <br/>
16
+ Rails setting (which is the default for running server in development environment).<br/>
17
+ Currently Reflexive isn't compatible with this setting and you may want to<br/>
18
+ either set <code>config.cache_classes = true</code> in your environment configuration<br/>
19
+ file or run the server in production mode with <br/><code>rails s --environment=production</code>
20
+ </div>
21
+ <% end %>
22
+
13
23
  <div class="dashboard-link">
14
24
  <%= link_to("Reflexive Dashboard", dashboard_path) unless request.path == dashboard_path %>
15
25
  </div>
@@ -1,9 +1,17 @@
1
1
  <h2>
2
2
  <%= @klass.name %>#<%= @method_name %>
3
3
  </h2>
4
+
5
+ <div>
6
+ Documentation provided by <a href="http://apidock.com/">APIdock</a>
7
+ <%= link_to apidock_path(@klass.name, @level, @method_name),
8
+ apidock_path(@klass.name, @level, @method_name) %> :
9
+
10
+ </div>
11
+
4
12
  <%= content_tag :iframe,
5
13
  "",
6
- :src => apidock_path(@klass.name, @method_name),
14
+ :src => apidock_path(@klass.name, @level, @method_name),
7
15
  :frameborder => 0,
8
16
  :style => "width: 960px; height: 100%; position: absolute",
9
17
  :id => "apidock" %>
@@ -0,0 +1,19 @@
1
+ <div>
2
+ Calling <code><%= @name %></code> <%= @level %> method from
3
+ <code><%= @klass %></code> can dispatch to following methods
4
+ </div>
5
+
6
+ <% if @last_resort_lookup_used %>
7
+ <div>
8
+ Note: the list of methods below was generated using last resort lookup
9
+ algorithm, i.e. by just looking for named method in any class/module
10
+ currently loaded.
11
+ </div>
12
+ <% end %>
13
+
14
+ <div>
15
+ <% links = @definitions.
16
+ sort_by { |klass, _, _| klass.to_s }.
17
+ map { |d| full_name_link_to_method(*d) } %>
18
+ <%= content_tag :pre, links.join("\n") %>
19
+ </div>
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflexive
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
7
+ - 1
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ version: 0.1.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Evgeniy Dolzhenko
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-05-17 00:00:00 -07:00
17
+ date: 2010-05-20 00:00:00 -07:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -24,12 +23,13 @@ dependencies:
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
- - - ">="
26
+ - - "="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
29
+ - 1
30
+ - 1
31
31
  - 0
32
- version: "0"
32
+ version: 1.1.0
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  - !ruby/object:Gem::Dependency
@@ -38,12 +38,12 @@ dependencies:
38
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - ">="
41
+ - - "="
42
42
  - !ruby/object:Gem::Version
43
- hash: 3
44
43
  segments:
44
+ - 1
45
45
  - 0
46
- version: "0"
46
+ version: "1.0"
47
47
  type: :runtime
48
48
  version_requirements: *id002
49
49
  - !ruby/object:Gem::Dependency
@@ -52,12 +52,13 @@ dependencies:
52
52
  requirement: &id003 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
- - - ">="
55
+ - - "="
56
56
  - !ruby/object:Gem::Version
57
- hash: 3
58
57
  segments:
59
58
  - 0
60
- version: "0"
59
+ - 3
60
+ - 40
61
+ version: 0.3.40
61
62
  type: :runtime
62
63
  version_requirements: *id003
63
64
  - !ruby/object:Gem::Dependency
@@ -66,77 +67,108 @@ dependencies:
66
67
  requirement: &id004 !ruby/object:Gem::Requirement
67
68
  none: false
68
69
  requirements:
69
- - - ">="
70
+ - - "="
70
71
  - !ruby/object:Gem::Version
71
- hash: 3
72
72
  segments:
73
73
  - 0
74
- version: "0"
74
+ - 9
75
+ - 3
76
+ version: 0.9.3
75
77
  type: :runtime
76
78
  version_requirements: *id004
77
79
  - !ruby/object:Gem::Dependency
78
- name: rdiscount
80
+ name: rails
79
81
  prerelease: false
80
82
  requirement: &id005 !ruby/object:Gem::Requirement
81
83
  none: false
82
84
  requirements:
83
- - - ">="
85
+ - - "="
84
86
  - !ruby/object:Gem::Version
85
- hash: 3
86
87
  segments:
88
+ - 3
87
89
  - 0
88
- version: "0"
89
- type: :runtime
90
+ - 0
91
+ - beta3
92
+ version: 3.0.0.beta3
93
+ type: :development
90
94
  version_requirements: *id005
91
95
  - !ruby/object:Gem::Dependency
92
- name: rails
96
+ name: rspec
93
97
  prerelease: false
94
98
  requirement: &id006 !ruby/object:Gem::Requirement
95
99
  none: false
96
100
  requirements:
97
101
  - - "="
98
102
  - !ruby/object:Gem::Version
99
- hash: -690468206
100
103
  segments:
101
- - 3
104
+ - 2
102
105
  - 0
103
106
  - 0
104
- - beta3
105
- version: 3.0.0.beta3
107
+ - beta
108
+ - 8
109
+ version: 2.0.0.beta.8
106
110
  type: :development
107
111
  version_requirements: *id006
108
112
  - !ruby/object:Gem::Dependency
109
- name: rspec
113
+ name: sinatra-reloader
110
114
  prerelease: false
111
115
  requirement: &id007 !ruby/object:Gem::Requirement
112
116
  none: false
113
117
  requirements:
114
118
  - - "="
115
119
  - !ruby/object:Gem::Version
116
- hash: -44051750
117
120
  segments:
118
- - 2
119
- - 0
120
121
  - 0
121
- - beta
122
- - 8
123
- version: 2.0.0.beta.8
122
+ - 4
123
+ - 1
124
+ version: 0.4.1
124
125
  type: :development
125
126
  version_requirements: *id007
126
127
  - !ruby/object:Gem::Dependency
127
- name: sinatra-reloader
128
+ name: thin
128
129
  prerelease: false
129
130
  requirement: &id008 !ruby/object:Gem::Requirement
130
131
  none: false
131
132
  requirements:
132
- - - ">="
133
+ - - "="
133
134
  - !ruby/object:Gem::Version
134
- hash: 3
135
135
  segments:
136
- - 0
137
- version: "0"
136
+ - 1
137
+ - 2
138
+ - 7
139
+ version: 1.2.7
138
140
  type: :development
139
141
  version_requirements: *id008
142
+ - !ruby/object:Gem::Dependency
143
+ name: rack-test
144
+ prerelease: false
145
+ requirement: &id009 !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - "="
149
+ - !ruby/object:Gem::Version
150
+ segments:
151
+ - 0
152
+ - 5
153
+ - 3
154
+ version: 0.5.3
155
+ type: :development
156
+ version_requirements: *id009
157
+ - !ruby/object:Gem::Dependency
158
+ name: webrat
159
+ prerelease: false
160
+ requirement: &id010 !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - "="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 0
167
+ - 7
168
+ - 1
169
+ version: 0.7.1
170
+ type: :development
171
+ version_requirements: *id010
140
172
  description:
141
173
  email:
142
174
  - dolzenko@gmail.com
@@ -153,10 +185,12 @@ files:
153
185
  - lib/reflexive/columnizer.rb
154
186
  - lib/reflexive/constantize.rb
155
187
  - lib/reflexive/core_ext/kernel/singleton_class.rb
188
+ - lib/reflexive/core_ext/module/reflexive_instance_methods.rb
156
189
  - lib/reflexive/descendants.rb
157
190
  - lib/reflexive/faster_open_struct.rb
158
191
  - lib/reflexive/helpers.rb
159
192
  - lib/reflexive/methods.rb
193
+ - lib/reflexive/method_lookup.rb
160
194
  - lib/reflexive/parse_tree_top_down_walker.rb
161
195
  - lib/reflexive/reflexive_ripper.rb
162
196
  - lib/reflexive/routing_helpers.rb
@@ -174,12 +208,16 @@ files:
174
208
  - views/files_show.erb
175
209
  - views/layout.erb
176
210
  - views/methods_apidock.erb
211
+ - views/methods_choose.erb
177
212
  - views/methods_definition.erb
178
213
  - views/methods_rubydoc.erb
179
214
  - spec/coderay_html_encoder_spec.rb
180
215
  - spec/coderay_ruby_scanner_spec.rb
216
+ - spec/integration_spec.rb
217
+ - spec/integration_spec_fixture.rb
181
218
  - spec/io_interceptor.rb
182
219
  - spec/methods_spec.rb
220
+ - spec/method_lookup_spec.rb
183
221
  - spec/rails_integration_spec.rb
184
222
  - spec/rails_integration_spec_helper.rb
185
223
  - spec/reflexive_ripper_spec.rb
@@ -206,7 +244,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
244
  requirements:
207
245
  - - ">="
208
246
  - !ruby/object:Gem::Version
209
- hash: 49
210
247
  segments:
211
248
  - 1
212
249
  - 9
@@ -217,7 +254,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
254
  requirements:
218
255
  - - ">="
219
256
  - !ruby/object:Gem::Version
220
- hash: 3
221
257
  segments:
222
258
  - 0
223
259
  version: "0"