tarantula 0.0.8.1 → 0.1.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.
- data/README.rdoc +80 -51
- data/Rakefile +33 -44
- data/VERSION.yml +4 -0
- data/examples/example_helper.rb +50 -0
- data/{test/relevance/core_extensions/ellipsize_test.rb → examples/relevance/core_extensions/ellipsize_example.rb} +1 -1
- data/{test/relevance/core_extensions/file_test.rb → examples/relevance/core_extensions/file_example.rb} +1 -1
- data/{test/relevance/core_extensions/response_test.rb → examples/relevance/core_extensions/response_example.rb} +5 -5
- data/{test/relevance/core_extensions/test_case_test.rb → examples/relevance/core_extensions/test_case_example.rb} +3 -3
- data/{test/relevance/tarantula/attack_form_submission_test.rb → examples/relevance/tarantula/attack_form_submission_example.rb} +1 -1
- data/{test/relevance/tarantula/attack_handler_test.rb → examples/relevance/tarantula/attack_handler_example.rb} +1 -1
- data/{test/relevance/tarantula/crawler_test.rb → examples/relevance/tarantula/crawler_example.rb} +3 -3
- data/{test/relevance/tarantula/form_test.rb → examples/relevance/tarantula/form_example.rb} +1 -1
- data/{test/relevance/tarantula/form_submission_test.rb → examples/relevance/tarantula/form_submission_example.rb} +1 -1
- data/{test/relevance/tarantula/html_document_handler_test.rb → examples/relevance/tarantula/html_document_handler_example.rb} +1 -1
- data/{test/relevance/tarantula/html_report_helper_test.rb → examples/relevance/tarantula/html_report_helper_example.rb} +1 -1
- data/{test/relevance/tarantula/html_reporter_test.rb → examples/relevance/tarantula/html_reporter_example.rb} +3 -3
- data/{test/relevance/tarantula/invalid_html_handler_test.rb → examples/relevance/tarantula/invalid_html_handler_example.rb} +1 -1
- data/{test/relevance/tarantula/io_reporter_test.rb → examples/relevance/tarantula/io_reporter_example.rb} +2 -2
- data/{test/relevance/tarantula/link_test.rb → examples/relevance/tarantula/link_example.rb} +21 -15
- data/{test/relevance/tarantula/log_grabber_test.rb → examples/relevance/tarantula/log_grabber_example.rb} +1 -1
- data/{test/relevance/tarantula/rails_init_test.rb → examples/relevance/tarantula/rails_init_example.rb} +3 -3
- data/{test/relevance/tarantula/rails_integration_proxy_test.rb → examples/relevance/tarantula/rails_integration_proxy_example.rb} +6 -12
- data/{test/relevance/tarantula/result_test.rb → examples/relevance/tarantula/result_example.rb} +2 -2
- data/{test/relevance/tarantula/tidy_handler_test.rb → examples/relevance/tarantula/tidy_handler_example.rb} +1 -1
- data/{test/relevance/tarantula/transform_test.rb → examples/relevance/tarantula/transform_example.rb} +2 -3
- data/{test/relevance/tarantula_test.rb → examples/relevance/tarantula_example.rb} +3 -3
- data/laf/v2/detail.html +23 -5
- data/laf/v2/index.html +1 -1
- data/laf/v2/stylesheets/tarantula.v2.css +77 -5
- data/lib/relevance/core_extensions/metaclass.rb +78 -0
- data/lib/relevance/tarantula.rb +1 -4
- data/lib/relevance/tarantula/link.rb +1 -1
- data/lib/relevance/tarantula/rails_integration_proxy.rb +1 -3
- data/template/tarantula_test.rb +12 -2
- metadata +54 -190
- data/init.rb +0 -1
- data/install.rb +0 -1
- data/manifest.txt +0 -102
- data/rails/init.rb +0 -4
- data/tarantula.gemspec +0 -56
- data/test/test_helper.rb +0 -34
- data/uninstall.rb +0 -1
- data/vendor/xss-shield/MIT-LICENSE +0 -20
- data/vendor/xss-shield/README +0 -76
- data/vendor/xss-shield/init.rb +0 -16
- data/vendor/xss-shield/lib/xss_shield.rb +0 -6
- data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +0 -111
- data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +0 -42
- data/vendor/xss-shield/lib/xss_shield/safe_string.rb +0 -47
- data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +0 -40
- data/vendor/xss-shield/test/test_actionview_integration.rb +0 -40
- data/vendor/xss-shield/test/test_erb.rb +0 -44
- data/vendor/xss-shield/test/test_haml.rb +0 -43
- data/vendor/xss-shield/test/test_helpers.rb +0 -25
- data/vendor/xss-shield/test/test_safe_string.rb +0 -55
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe 'Relevance::Tarantula::IOReporter' do
|
4
4
|
it "reports errors to stderr and then raises" do
|
@@ -6,6 +6,6 @@ describe 'Relevance::Tarantula::IOReporter' do
|
|
6
6
|
reporter.report stub(:code => "404", :url => "/uh-oh", :success => false)
|
7
7
|
$stderr.expects(:puts).with("****** FAILURES")
|
8
8
|
$stderr.expects(:puts).with("404: /uh-oh")
|
9
|
-
lambda {reporter.finish_report("test_user_pages")}.should
|
9
|
+
lambda {reporter.finish_report("test_user_pages")}.should raise_error(RuntimeError)
|
10
10
|
end
|
11
11
|
end
|
@@ -1,42 +1,48 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::Link" do
|
4
4
|
include ActionView::Helpers::UrlHelper
|
5
5
|
|
6
|
+
it "does not raise an error when initializing without href attribtue" do
|
7
|
+
link = Relevance::Tarantula::Link.new(Hpricot('<a="/foo">foo</a>').at('a'))
|
8
|
+
link.href.should == nil
|
9
|
+
link.method.should == :get
|
10
|
+
end
|
11
|
+
|
6
12
|
it "parses anchor tags" do
|
7
13
|
link = Relevance::Tarantula::Link.new(Hpricot('<a href="/foo">foo</a>').at('a'))
|
8
|
-
|
9
|
-
|
14
|
+
link.href.should == '/foo'
|
15
|
+
link.method.should == :get
|
10
16
|
end
|
11
17
|
|
12
18
|
it "parses anchor tags with POST 'method'" do
|
13
19
|
link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
|
14
|
-
|
15
|
-
|
20
|
+
link.href.should == '/foo'
|
21
|
+
link.method.should == :post
|
16
22
|
end
|
17
23
|
|
18
24
|
it "parses anchor tags with PUT 'method'" do
|
19
25
|
link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
|
20
|
-
|
21
|
-
|
26
|
+
link.href.should == '/foo'
|
27
|
+
link.method.should == :put
|
22
28
|
end
|
23
29
|
|
24
30
|
it "parses anchor tags with DELETE 'method'" do
|
25
31
|
link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
|
26
|
-
|
27
|
-
|
32
|
+
link.href.should == '/foo'
|
33
|
+
link.method.should == :delete
|
28
34
|
end
|
29
35
|
|
30
36
|
it "parses link tags with text" do
|
31
37
|
link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar">bar</a>').at('link'))
|
32
|
-
|
33
|
-
|
38
|
+
link.href.should == '/bar'
|
39
|
+
link.method.should == :get
|
34
40
|
end
|
35
41
|
|
36
42
|
it "parses link tags without text" do
|
37
43
|
link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar" />').at('link'))
|
38
|
-
|
39
|
-
|
44
|
+
link.href.should == '/bar'
|
45
|
+
link.method.should == :get
|
40
46
|
end
|
41
47
|
|
42
48
|
# method_javascript_function needs this method
|
@@ -48,14 +54,14 @@ end
|
|
48
54
|
|
49
55
|
describe "possible conflict when user has an AR model named Link" do
|
50
56
|
it "does not taint Object with Relevance::Tarantula" do
|
51
|
-
Object.ancestors.
|
57
|
+
Object.ancestors.should_not include(Relevance::Tarantula)
|
52
58
|
end
|
53
59
|
|
54
60
|
it "doesnt break with a Link model" do
|
55
61
|
lambda {
|
56
62
|
class Link < ActiveRecord::Base
|
57
63
|
end
|
58
|
-
}.
|
64
|
+
}.should_not raise_error
|
59
65
|
end
|
60
66
|
|
61
67
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "../..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "../..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe "Rails init.rb" do
|
4
|
-
|
4
|
+
after { ENV.delete "RAILS_ENV" }
|
5
5
|
|
6
|
-
|
6
|
+
pending "requires main tarantula file if in test environment" do
|
7
7
|
ENV["RAILS_ENV"] = "test"
|
8
8
|
path = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. .. lib relevance tarantula]))
|
9
9
|
Object.any_instance.expects(:require).with('rake')
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::RailsIntegrationProxy rails_integration_test" do
|
4
4
|
before {
|
@@ -23,7 +23,7 @@ describe "Relevance::Tarantula::RailsIntegrationProxy rails_integration_test" do
|
|
23
23
|
|
24
24
|
it "has some useful defaults" do
|
25
25
|
crawler = Relevance::Tarantula::RailsIntegrationProxy.rails_integration_test(stub(:host => "foo.com"))
|
26
|
-
crawler.log_grabber.
|
26
|
+
crawler.log_grabber.should_not be_nil
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -34,7 +34,7 @@ describe "Relevance::Tarantula::RailsIntegrationProxy" do
|
|
34
34
|
@rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
|
35
35
|
@response = stub({:code => :foo})
|
36
36
|
@rip.integration_test = stub_everything(:response => @response)
|
37
|
-
@rip.send(http_method, "/url").should
|
37
|
+
@rip.send(http_method, "/url").should == @response
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -58,18 +58,12 @@ describe "Relevance::Tarantula::RailsIntegrationProxy patching" do
|
|
58
58
|
@rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
|
59
59
|
@rip.stubs(:rails_root).returns("faux_rails_root")
|
60
60
|
@response = stub_everything({:code => "404", :headers => {}, :content_type => "text/html"})
|
61
|
-
@response.meta.ancestors.
|
61
|
+
@response.meta.ancestors.should_not include(Relevance::CoreExtensions::Response)
|
62
62
|
@rip.patch_response("/url", @response)
|
63
|
-
@response.meta.ancestors.should
|
63
|
+
@response.meta.ancestors.should include(Relevance::CoreExtensions::Response)
|
64
64
|
@response.html?.should == true
|
65
65
|
end
|
66
|
-
|
67
|
-
it "ignores 404s for known static binary types" do
|
68
|
-
File.expects(:extension).returns("pdf")
|
69
|
-
@rip.expects(:log).with("Skipping /url (for now)")
|
70
|
-
@rip.patch_response("/url", @response)
|
71
|
-
end
|
72
|
-
|
66
|
+
|
73
67
|
it "replaces 404s with 200s, pulling content from public, for known text types" do
|
74
68
|
File.expects(:extension).returns("html")
|
75
69
|
@rip.expects(:static_content_file).with("/url").returns("File body")
|
data/{test/relevance/tarantula/result_test.rb → examples/relevance/tarantula/result_example.rb}
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::Result" do
|
4
4
|
before do
|
@@ -77,7 +77,7 @@ describe "Relevance::Tarantula::Result allowed errors" do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it "chains to super method missing" do
|
80
|
-
lambda{Relevance::Tarantula::Result.allow_xxx_for}.should
|
80
|
+
lambda{Relevance::Tarantula::Result.allow_xxx_for}.should raise_error(NoMethodError)
|
81
81
|
end
|
82
82
|
|
83
83
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "../..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "../..", "example_helper.rb")
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::Transform" do
|
4
4
|
it "can do a simple replace" do
|
@@ -15,7 +15,6 @@ describe "Relevance::Tarantula::Transform" do
|
|
15
15
|
it "cannot access groups from a block, despite Ruby docs" do
|
16
16
|
p = Proc.new {|value| $1.upcase}
|
17
17
|
t = Relevance::Tarantula::Transform.new(/([aeiou])/, p)
|
18
|
-
lambda {t["hello world"]}.should
|
19
|
-
"undefined method `upcase' for nil:NilClass"
|
18
|
+
lambda {t["hello world"]}.should raise_error(NoMethodError)
|
20
19
|
end
|
21
20
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", "
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "example_helper.rb")
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Relevance::Tarantula do
|
4
4
|
include Relevance::Tarantula
|
5
5
|
attr_accessor :verbose
|
6
6
|
|
@@ -17,7 +17,7 @@ describe "Relevance::Tarantula" do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "puts RAILS_ROOT behind a method call" do
|
20
|
-
lambda{rails_root}.should
|
20
|
+
lambda{rails_root}.should raise_error(NameError)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/laf/v2/detail.html
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
5
|
<head>
|
6
6
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
-
<link rel="stylesheet" href="stylesheets/tarantula.v2.css" type="text/css" media="screen" title="no title" charset="utf-8"
|
7
|
+
<link rel="stylesheet" href="stylesheets/tarantula.v2.css" type="text/css" media="screen" title="no title" charset="utf-8" />
|
8
8
|
|
9
9
|
<title>Detail</title>
|
10
10
|
|
@@ -22,18 +22,36 @@
|
|
22
22
|
</div>
|
23
23
|
<div id="page">
|
24
24
|
<ul class="tabs">
|
25
|
-
<li><a href="index.html"
|
25
|
+
<li><a href="index.html">« Failures</a></li>
|
26
26
|
<li><a href="#" class="active">Data</a></li>
|
27
27
|
<li><a href="#">Body</a></li>
|
28
28
|
<li><a href="#">Log</a></li>
|
29
29
|
</ul>
|
30
30
|
<div id="report">
|
31
31
|
<h3>Detail of GET /widgets/1 <em>Generated on Friday January 9, 2009 at 11:01:45am</em></h3>
|
32
|
-
<p><b>
|
33
|
-
<p><b>Response</b> 500</p>
|
32
|
+
<p><b>Resource</b> <a href="#">http://localhost:3000/widgets/6</a></p>
|
33
|
+
<p><b>Response</b> <span class="r5">500</span></p>
|
34
34
|
<p><b>Referrer</b> /random/30</p>
|
35
35
|
|
36
|
-
|
36
|
+
<table id="output">
|
37
|
+
<tbody>
|
38
|
+
<tr>
|
39
|
+
<th colspan="2">#</th>
|
40
|
+
</tr>
|
41
|
+
<tr>
|
42
|
+
<td class="numbers">
|
43
|
+
<span class="line number">1</span>
|
44
|
+
<span class="line number">2</span>
|
45
|
+
<span class="line number">3</span>
|
46
|
+
</td>
|
47
|
+
<td class="lines">
|
48
|
+
<span class="line">{:param1 => :value, :param2 => :another_value} </span>
|
49
|
+
<span class="line">{:param1 => :value, :param2 => :another_value} </span>
|
50
|
+
<span class="line">{:param1 => :value, :param2 => :another_value} </span>
|
51
|
+
</td>
|
52
|
+
</tr>
|
53
|
+
</tbody>
|
54
|
+
</table>
|
37
55
|
</div>
|
38
56
|
</div>
|
39
57
|
</div>
|
data/laf/v2/index.html
CHANGED
@@ -158,14 +158,15 @@ div#page ul.tabs {
|
|
158
158
|
left: 7px;
|
159
159
|
}
|
160
160
|
|
161
|
-
|
161
|
+
#list {
|
162
162
|
width: 100%;
|
163
163
|
}
|
164
164
|
|
165
|
-
|
165
|
+
#list th, #list th a, #list tfoot td {
|
166
166
|
background: #b9b9a9;
|
167
167
|
color: #463c38;
|
168
168
|
text-decoration: none;
|
169
|
+
|
169
170
|
}
|
170
171
|
|
171
172
|
.sort {
|
@@ -176,14 +177,14 @@ div#page table th, div #page th a, div#page tfoot td {
|
|
176
177
|
opacity: 0.5;
|
177
178
|
}
|
178
179
|
|
179
|
-
|
180
|
+
#list th, #list th a:hover span {
|
180
181
|
filter:alpha(opacity=100);
|
181
182
|
-moz-opacity:1;
|
182
183
|
-khtml-opacity: 1;
|
183
184
|
opacity: 1;
|
184
185
|
}
|
185
186
|
|
186
|
-
|
187
|
+
#list td, #list th {
|
187
188
|
text-align: center;
|
188
189
|
padding: 4px;
|
189
190
|
font-size: 14px;
|
@@ -202,12 +203,18 @@ div#page table caption {
|
|
202
203
|
padding: 7px;
|
203
204
|
background: #d0d0c4;
|
204
205
|
border-bottom: 2px solid #aba7a1;
|
206
|
+
-moz-border-radius-topleft: 2px;
|
207
|
+
-moz-border-radius-topright: 2px;
|
205
208
|
}
|
206
209
|
|
207
|
-
|
210
|
+
#list tbody td {
|
208
211
|
background: #f2f2eb;
|
209
212
|
}
|
210
213
|
|
214
|
+
#list tfoot td {
|
215
|
+
line-height: 18px;
|
216
|
+
}
|
217
|
+
|
211
218
|
tr.even td {
|
212
219
|
background: #e9e9e2 !important;
|
213
220
|
}
|
@@ -250,3 +257,68 @@ span.r5 {
|
|
250
257
|
background-color: #c40000;
|
251
258
|
border: 1px solid #dc0000;
|
252
259
|
}
|
260
|
+
|
261
|
+
/* Detail */
|
262
|
+
#report h3 {
|
263
|
+
background: #D0D0C4; font-weight: normal;
|
264
|
+
border-bottom: 2px solid #ABA7A1;
|
265
|
+
-moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px;
|
266
|
+
-webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px;
|
267
|
+
}
|
268
|
+
|
269
|
+
#report h3,
|
270
|
+
#report p {
|
271
|
+
width: 50%;
|
272
|
+
padding:6px 8px;
|
273
|
+
margin: 1px 0;
|
274
|
+
}
|
275
|
+
|
276
|
+
#report a {
|
277
|
+
color: #70B1CA
|
278
|
+
}
|
279
|
+
|
280
|
+
#report a:hover {
|
281
|
+
text-decoration: none;
|
282
|
+
}
|
283
|
+
|
284
|
+
#report p b {
|
285
|
+
color: #050505;
|
286
|
+
font-weight: normal;
|
287
|
+
}
|
288
|
+
|
289
|
+
#report p {
|
290
|
+
color: #463C38;
|
291
|
+
background: #f2f2eb;
|
292
|
+
line-height: 22px;
|
293
|
+
}
|
294
|
+
|
295
|
+
#report p span {
|
296
|
+
display: inline-block;
|
297
|
+
display: -moz-inline-block;
|
298
|
+
margin: 0;
|
299
|
+
padding: 2px 6px;
|
300
|
+
line-height: 16px;
|
301
|
+
}
|
302
|
+
|
303
|
+
#report h3 em {
|
304
|
+
display: block;
|
305
|
+
font-family: Consolas, Lucida Console, Monaco, monospace;
|
306
|
+
font-size: 75%;
|
307
|
+
font-style: normal;
|
308
|
+
font-weight: normal;
|
309
|
+
color: #463C38;
|
310
|
+
line-height: 22px;
|
311
|
+
}
|
312
|
+
|
313
|
+
/* Output */
|
314
|
+
#output {margin: 10px 0; width: 100%; font-size: 82.5%;}
|
315
|
+
#output th { background: #b9b9a9; text-align: left; padding-left: 2.25em; font-weight: normal; line-height: 18px; color: #463C38; border-bottom: 1px solid #fff;
|
316
|
+
-moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px;
|
317
|
+
-webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px;
|
318
|
+
}
|
319
|
+
#output td { background: #f2f2eb; padding: 1px; line-height: 18px; }
|
320
|
+
#output { font-family: Consolas, Lucida Console, Monaco, monospace; }
|
321
|
+
#output .numbers { width: 3em; text-align: right; border-right: 1px solid #fff;}
|
322
|
+
#output .lines { width: auto; text-align: left;}
|
323
|
+
#output .line { display: block; text-align: left; padding: 1px 4px;}
|
324
|
+
#output .line.number { text-align: right; color: #585850; }
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# This is a direct copy of the facets library metaclass stuff.
|
2
|
+
# used by Tarantula pulling in all of Facets doesn't make sense here.
|
3
|
+
|
4
|
+
# From lib/core/facets/metaid.rb
|
5
|
+
module Kernel
|
6
|
+
def meta_alias(*args)
|
7
|
+
meta_class do
|
8
|
+
alias_method(*args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def meta_eval(str=nil, &blk)
|
13
|
+
if str
|
14
|
+
meta_class.instance_eval(str)
|
15
|
+
else
|
16
|
+
meta_class.instance_eval(&blk)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def meta_def( name, &block )
|
21
|
+
meta_class do
|
22
|
+
define_method( name, &block )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def meta_class(&block)
|
27
|
+
if block_given?
|
28
|
+
(class << self; self; end).class_eval(&block)
|
29
|
+
else
|
30
|
+
(class << self; self; end)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :metaclass, :meta_class
|
35
|
+
|
36
|
+
def eigenclass
|
37
|
+
(class << self; self; end)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Module
|
42
|
+
def class_def name, &blk
|
43
|
+
class_eval { define_method name, &blk }
|
44
|
+
end
|
45
|
+
|
46
|
+
protected :attr
|
47
|
+
protected :attr_reader
|
48
|
+
protected :attr_writer
|
49
|
+
protected :attr_accessor
|
50
|
+
protected :remove_method
|
51
|
+
protected :undef_method
|
52
|
+
end
|
53
|
+
|
54
|
+
# From /lib/more/facets/kernel/meta.rb
|
55
|
+
module Kernel
|
56
|
+
def meta
|
57
|
+
@_meta_functor ||= Functor.new do |op,*args|
|
58
|
+
(class << self; self; end).send(op,*args)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# From /lib/core/facets/functor.rb
|
64
|
+
class Functor
|
65
|
+
private(*instance_methods.select { |m| m !~ /(^__|^binding$)/ })
|
66
|
+
|
67
|
+
def initialize(&function)
|
68
|
+
@function = function
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_proc
|
72
|
+
@function
|
73
|
+
end
|
74
|
+
|
75
|
+
def method_missing(op, *args, &blk)
|
76
|
+
@function.call(op, *args, &blk)
|
77
|
+
end
|
78
|
+
end
|